国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

shadow-cljs: JavaScript 依賴的實踐

張漢慶 / 2601人閱讀

摘要:原文原作者是作者是一個面向開發者友好的編譯器之前關于依賴的文章問題前景里面我解釋了為什么當中采用了和默認的方案不同的做法簡單回顧下或者的寫法難以擴張自定義的打包實際當中使用繁瑣目前對大部分的模塊的處理不夠可靠自定義了一個而移除了

原文 https://code.thheller.com/blo...
原作者是 shadow-cljs 作者, shadow-cljs 是一個面向 JavaScript 開發者友好的 ClojureScript 編譯器.

之前關于 js 依賴的文章(問題, 前景)里面, 我解釋了為什么 shadow-cljs 當中采用了和 ClojureScript 默認的方案不同的做法. 簡單回顧下:

cljsjs 或者 :foreign-libs 的寫法難以擴張

自定義的打包實際當中使用繁瑣

Closure Compiler 目前對大部分的 npm 模塊的處理不夠可靠

shadow-cljs 自定義了一個 js bundler, 而移除了 :foreign-libs 的支持

安裝 js 依賴

幾乎所有的 npm 模塊都會寫一遍如何安裝. 現在對于 shadow-cljs 來說也是適用的. 比如有個類庫要你運行:

npm install the-thing

你照做就好. 不需要其他步驟了. 當然你喜歡的話可以用 yarn. 然后依賴就會被寫進 package.json 文件用于管理. 如果沒有 package.json 那就運行 npm init.

上面說到這些東西, 你可以用這個 QuickStart 模板 來試用.

試用 js 依賴

大部分的 npm 模塊也會寫一下具體的代碼表示怎樣使用模塊. "舊的" CommonJS 的寫法是用 require 調用. 翻譯到 ClojureScript 就是:

var react = require("react");
(ns my.app
  (:require ["react" :as react]))

不管 "string" 參數的地方用了什么然后被 require 調用, 我們都是這樣換成 ns :require. :as 的 alias 部分就隨你定義. 有了這個之后, 它就像是其他的 cljs 的命名空間那樣可以調用了:

(react/createElement "div" nil "helle world")

這跟以前 :foreign-libs 或者 CLJSJS 當中做的不一樣, 以前比如引入了 thingns 然后要用 js/Thing(或者其他全局導出的變量)來使用代碼. 現在可以用 ns 格式以及 :as 后面提供的名稱. 需要的話還可以寫 :refer:rename.

一些模塊會暴露一個函數, 那你可以寫 (:require ["thing" as thing]) 然后調用 (thing).

最近一些模塊開始用 ES6 的 import 語法作為例子了. 這些代碼除了一個 default 寫法以外, 基本上在 ClojureScript 能做到一一對應. 比如說翻譯下面的例子:

import defaultExport from "module-name";
import * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";
import { export1 , export2 } from "module-name";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";

到(包裹在 ns 里面的):

(:require ["module-name" :default defaultExport])
(:require ["module-name" :as name])
(:require ["module-name" :refer (export)])
(:require ["module-name" :rename {export alias}])
(:require ["module-name" :refer (export1) :rename {export2 alias2}])
(:require ["module-name" :refer (export) :default defaultExport])
(:require ["module-name" :as name :default defaultExport])
(:require ["module-name"])

其中 :default 參數目前只在 shadow-cljs 里面支持, 但是你也可以在這里投票幫助它進入到規范當中. 或者你也可以一直用 :as alias 然后調用 alias/default, 這樣你覺得能個標準的 cljs 始終保持兼容的話. 我覺得吧, 對于某些模塊來說啰嗦了點.

新的可能性

之前我們的使用打包之后的代碼, 可能會包含我們用不到的代碼. 某些模塊也說明了一些辦法可以只引入部分的模塊, 這樣最終構建的代碼體積會小一些.

react-virtualized 有個這樣的例子:

// You can import any component you want as a named export from "react-virtualized", eg
import { Column, Table } from "react-virtualized"

// But if you only use a few react-virtualized components,
// And you"re concerned about increasing your application"s bundle size,
// You can directly import only the components you need, like so:
import AutoSizer from "react-virtualized/dist/commonjs/AutoSizer"
import List from "react-virtualized/dist/commonjs/List"

那么很容易翻譯過去:

;; all
(:require ["react-virtualized" :refer (Column Table)])
;; one by one
(:require ["react-virtualized/dist/commonjs/AutoSizer" :default virtual-auto-sizer])
(:require ["react-virtualized/dist/commonjs/List" :default virtual-list])
查找 js 依賴

默認情況下 shadow-cljs 通過 npm 的方式引用查找所有 (:require ["thing" :as x]). 也就是說會查找 /node_modules/thing/... 當中的代碼. 為了對這個行為進行自定義, shadow-cljs 暴露了一個 :resolve 配置項, 你可以自己定義某些模塊如何查找.

使用 CDN

比如說頁面里的 React 從 CDN 上引用了. 這時候按說你可以用 js/React 了, 但是最好還是不要這樣. 你應該是繼續用 (:require ["react" :as react]), 同時在 shadow-cljs 里定義 react 怎樣查找. 這個配置在 shadow-cljs.edn 文件里配置:

{:builds
 {:app
  {:target :browser
   ...
   :js-options
   {:resolve {"react" {:target :global
                       :global "React"}}}}

  :server
  {:target :node-script
   ...}}}

現在 :app 這個構建會使用全局的 React 實例, 而在 :server 這個構建當中會繼續使用 react 的 npm 模塊. 不需要額外折騰代碼去完成需求.

重定向 require

某些模塊提供多個 "dist" 文件, 然后可能默認的那個剛好是在 shadow-cljs 里有問題的. 一個明顯的例子就是 d3. 他們默認的 "main" 指向 build/d3.node.js, 這個不是在瀏覽器里面用的版本. 他們的 ES6 代碼還觸發了 Closure Compiler 里的一個 bug, 所以我們不能用. 這樣的話我們就重定向到其他的引用去:

{:resolve {"d3" {:target :npm
                 :require "d3/build/d3.js"}}}

你也可以直接就寫 (:require ["d3/build/d3.js" :as d3]), 如果你只關心瀏覽器當中的使用的話.

使用本地文件

你還可以用 :resolve 來直接映射到一個項目中的本地文件:

{:resolve {"my-thing" {:target :file
                       :file "path/to/file.js"}}}

這里的 :file 總是相對于項目根路徑. 這個文件里可以用 require 或者 import/export, 這些隨后都會被處理好的.

遷移 cljsjs.*

很多 cljs 類庫還在用 CLJSJS 包, 它們在 shadow-cljs 里不能正常使用了, 因為 :foreign-libs 不再支持. 我提供了一個清晰的遷移路線, 只需要增加一個 shim 文件把 cljsjs.thing 映射回到原始的 npm 模塊, 然后把全局變量暴露出去.

比如 react 需要一個這樣的文件src/cljsjs/react.cljs:

(ns cljsjs.react
  (:require ["react" :as react]
            ["create-react-class" :as crc]))

(js/goog.object.set react "createClass" crc)
(js/goog.exportSymbol "React" react)

因為這樣的話每個人手動處理會麻煩, 所以我提供了 shadow-cljsjs 這個類庫來提供這個功能. 雖然不會包含每一個模塊, 但是我會持續添加. 歡迎來幫忙貢獻模塊.

不過它僅僅提供 shim 文件. 你還是需要用 npm install 安裝真實的模塊.

其他功能不能用怎么辦?

JavaScript 社區變化很快, 并不是每個人都一樣地寫代碼, 都一樣地分發代碼, 有些東西是 shadow-cljs 不能自動處理或者需要自定義 :resolve 配置的. 可能是會遇到 bug, 畢竟都是新東西.

遇到任何模塊不能按照預期地使用, 請報告. 在 #shadow-cljs 很容易找到我.

關于這篇文章的討論請移步 :clojurevese.

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89693.html

相關文章

  • Luxon 初步介紹(Moment 團隊日期另一個類庫)

    摘要:我不是的深度用戶只是日常會遇到一些時間格式化的需求之前用的都是不過對的感到有些不舒服同事介紹過里邊用不可變數據的風格設計的所以就試試上星星很多請放心食用是項目的某個維護者開發的按照他個人想法進行了改進除了不可變性使用的工具做了更新也嘗試到時 我不是 Moment 的深度用戶, 只是日常會遇到一些時間格式化的需求,之前用的都是 Moment, 不過對 Moment 的 mutable A...

    stormzhang 評論0 收藏0
  • 前端每周清單第 40 期: JS Core 與 Cost,Node 內存溢出調試,Softwar

    摘要:已被所有主流瀏覽器支持在過去幾周蘋果的瀏覽器與微軟的瀏覽器分別發布新版本,支持了,再加上早已支持的和,已得到所有主流瀏覽器支持。 showImg(https://segmentfault.com/img/remote/1460000012086220?w=1240&h=823); 前端每周清單第 40 期: JS 的 Core 與 Cost,Node 內存溢出調試,Software 2...

    番茄西紅柿 評論0 收藏0
  • 預告:JavaScript模塊全覽

    摘要:之前寫的文章急速全棧教程得到了不錯的閱讀量,霸屏掘金頭條天,點贊過千,閱讀近萬,甚至還有人在評論區打廣告,可見也是一個小小的生態了。今天看到的霸屏的,也是講全棧的,見參考文章接下來要寫的是模塊。全局命名污染和命名沖突依賴管理。 之前寫的文章急速Js全棧教程得到了不錯的閱讀量,霸屏掘金頭條3天,點贊過千,閱讀近萬,甚至還有人在評論區打廣告,可見也是一個小小的生態了;)。看來和JS全棧有關...

    focusj 評論0 收藏0
  • RequireJS配置項筆記

    摘要:讀不順中文文檔,對應中文文檔,自行翻譯的如果有問題錯誤,歡迎指點修改配置選項方法一在頂級頁面或頂級腳本文件沒有定義模塊的腳本文件中配置方法二在主模塊中配置缺點主模塊異步加載,多入口的話,會隨機報錯方法三在調用之前,將配置定義為全局變量配置在 讀不順中文文檔,對應中文文檔,自行翻譯的……如果有問題/錯誤,歡迎指點; 修改配置選項: 方法一、 requi...

    FWHeart 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<