mkdir hello-bundler
cd hello-bundler
本指南要求使用 ClojureScript 1.10.741 或更高版本,并假设您熟悉 快速入门.
本页介绍如何将 ClojureScript 与典型的 JavaScript 打包器(如 Webpack)集成。您应该已安装 Node.js。本指南假设您已阅读快速入门指南。本指南大量借鉴了 关于 Webpack 2 的优秀指南。
虽然我们在这里使用 Webpack,但这些说明很容易适应其他打包器,例如用于 React Native 的 Metro。
首先创建一个项目目录
mkdir hello-bundler
cd hello-bundler
创建一个 deps.edn
文件,其中包含以下内容
{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}}}
创建一个空的 package.json
文件
echo "{}" > package.json
添加 webpack 及其命令行工具
npm install --save-dev webpack webpack-cli
现在我们准备设置我们的 JS 依赖项。
安装 react 和 react-dom
npm install --save react react-dom
现在创建一个 src/hello_bundler/core.cljs
文件,其中包含以下内容
(ns hello-bundler.core
(:require [react]))
(.log js/console react/Component)
注意,我们像正常 require 和命名空间一样要求 React。
为了使其正常工作,我们需要设置几个编译器选项。创建一个 build.edn
文件,其中包含以下内容
{:main hello-bundler.core
:output-to "out/index.js"
:output-dir "out"
:target :bundle
:bundle-cmd {:none ["npx" "webpack" "./out/index.js" "-o" "out" "--mode=development"]
:default ["npx" "webpack" "./out/index.js" "-o" "out"]}
:closure-defines {cljs.core/*global* "window"}} ;; needed for advanced
我们的构建将生成 out/index.js
,这正是 Webpack 正在寻找的入口文件。我们将打包器结果写回到输出目录。
请注意新的 :target :bundle
选项。这确保生成的代码与可以处理 Node.js 风格 require
的流行 JavaScript 打包器兼容。它还设置了一系列其他明智的默认值,例如外部声明推断,因此高级编译将可以正常工作。:bundle-cmd
只是一个在 ClojureScript 构建完成后运行的任意 shell 命令。对于像 Metro 这样的监听打包器,您可能不会费心使用 :bundle-cmd
。
让我们看看它的实际效果,以下操作将构建您的项目,然后启动 REPL
clj -M -m cljs.main -co build.edn -v -c -r
您的默认浏览器将打开 https://127.0.0.1:9000。打开开发者控制台,您应该看到已记录了 React.Component
。
在 REPL 中,您可以要求 react
并与之交互
user> (require 'react)
您可能会发现您希望使用来自 node_modules
的 React,可能是因为最新的捆绑版本尚未出现在 CLJSJS 上。但是,您仍然希望使用一些 ClojureScript React 绑定,例如 Reagent。ClojureScript 开箱即用地支持此功能。
为了演示这一点,将您的 deps.edn
更改为以下内容
{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}
reagent {:mvn/version "0.10.0" :exclusions [cljsjs/react cljsjs/react-dom]}}}
将您的源文件更改为以下内容
(ns hello-bundler.core
(:require [goog.dom :as gdom]
[reagent.dom :as dom]))
(defn simple-component []
[:div
[:p "I am a component!"]
[:p.someclass
"I have " [:strong "bold"]
[:span {:style {:color "red"}} " and red "] "text."]])
(dom/render [simple-component] (gdom/getElement "app"))
重建您的项目,运行 REPL
clj -M -m cljs.main -co build.edn -v -c -r
为了验证外部声明推断是否允许高级编译正常工作,让我们进行高级构建。REPL 在高级编译下不起作用,因此您必须手动打开 https://127.0.0.1:9000
clj -M -m cljs.main -co build.edn -O advanced -v -c -s
就是这样!
使用 :target :bundle
构建 Web 工作线程时,您使用 webpack(或您喜欢的打包器)添加 Web 工作线程引导程序。
因此,您的构建的 :target
仍然是 :bundle
(而不是 :webworker
),但您将告诉您的打包器构建一个 Web 工作线程。例如,使用 webpack,您将 --target=webworker
参数添加到您的 :bundle-cmd
条目中。
您还需要将 cljs.core/global
定义为 "self"
(而不是浏览器构建中的 "window"
)。
一个示例 build-webworker.edn
可能看起来像
{:main hello-bundler.webworker
:output-to "out/worker/index.js"
:output-dir "out/worker"
:target :bundle
:bundle-cmd {:none ["npx" "webpack" "out/worker/index.js" "-o" "out/worker/main.js" "--target=webworker" "--mode=development"]
:default ["npx" "webpack" "out/worker/index.js" "-o" "out/worker/main.js" "--target=webworker"]}
:closure-defines {cljs.core/*global* "self"}} ;; needed for advanced
原始作者:David Nolen