與lodash一樣,庫@yamato-daiwa/es-extensions建議了 BrowserJS 和 NodeJS 的通用函式,但與 lodash 不同的是,它具有可重新匯出的單個主檔案 index.js。
要求
這個庫:
- 必須在瀏覽器環境中使用 Webpack(達到 ??)
- 必須為 BrowserJS 提供 Webpack 的搖樹(換句話說,在生產構建中切斷未使用的功能),其中每千位元組計數(達到??)。
- 必須在 NodeJS 環境中作業。
- 必須使用ts-node
主要問題
沖突點是模塊型別。為了使 Webpack 的樹搖動可用,需要 ES 模塊,但目前 NodeJS 僅支持 CommonJS 模塊,并且在 ts-node 中,ES 模塊支持是有限的(尤其是在庫匯出的情況下)。
我們擁有的是:
| 模塊型別 | BrowserJS (Webpack) | 搖樹 | 節點 | ts節點 |
|---|---|---|---|---|
| 通用JS | 是的 | 不 | 是的 | 是的 |
| ES20XX | 是的 | 是的 | 不 | 有限的 |
由于搖樹對 BroswerJS 至關重要,因此已經決定通過 ES2020 模塊分發該庫。但是這樣一來,就會失去對 NodeJS 和 ts-node 的支持。
即使使用 Webpack 構建 NodeJS 應用程式,但不建議捆綁NodeJS庫(使用webpack 節點模塊外部模塊來排除它們),如果不將@yamato-daiwa/es-extensions帶有 ES 模塊的應用程式添加到排除webpack 節點模塊中,應用程式也會崩潰外部。
再現
在這個 repro 中,npm run "Webpack:ProductionBuild"將構建檔案BrowserJS.js和NodeJS.js適當的環境。因為源代碼只使用isUndefined了"@yamato-daiwa/es-extensions"庫的功能,所以BrowserJS.js不能有任何其他功能(Webpack的搖樹):
(()=>{"use strict";console.log(!1),console.log("End of the script")})();
嗯,這是明確的挑戰。這個問題的主題是NodeJS.js:
(()=>{"use strict";const e=require("@yamato-daiwa/es-extensions");console.log((0,e.isUndefined)("ALPHA")),console.log("End of the script")})();
如果我們嘗試運行它,則會出現錯誤:
C:\Users\***\WebpackDoesNotCuttOfTheUnusedFunctionality\ConsumingProject\node_modules\@yamato-dai
wa\es-extensions\Distributable\index.js:6
export { default as formatNumberWith4KetaKanji } from "./Numbers/formatNumberWith4KetaKanji";
Now let's try to run it via ts-node (npm run "TSNode test"):
> ts-node index.ts
(node:18148) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
C:\Users\***\WebpackDoesNotCuttOfTheUnusedFunctionality\ConsumingProject\index.ts:1
import { isUndefined } from "@yamato-daiwa/es-extensions";
Does in mean "you must change the library"?
Note
This question has been asked before TypeScript 4.5 release. Maybe its new functionality will solve these problems?
uj5u.com熱心網友回復:
檔案中的"main"條目package.json應始終采用 commonjs 格式。該"module"條目應始終ES模塊。現在,您已"main"指向 es 模塊,這些模塊將無法正確決議(ts-node例如您的錯誤)。
通常,如果您想為消費者提供選擇權,您將在可分發檔案中創建 2 個版本。
(您需要洗掉這些 json 檔案中的注釋)
// tsconfig-esm.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "ES2020",
// es module build target
"outDir": "Distributable/esm"
}
}
// tsconfig-cjs.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
// commonjs build target
"outDir": "Distributable/cjs",
// the other one will build types, so not needed here
"declaration": false
}
}
然后,在您的package.json:
"main": "./Distributable/cjs/index.js",
"module": "./Distributable/esm/index.js",
"types": "./Distributable/esm/index.d.ts",
"scripts": {
"build": "rimraf Distributable & tsc -p tsconfig-cjs.json && tsc -p tsconfig-esm.json",
"Lint": "eslint Source Tests"
},
"files": [
"Distributable"
],
"devDependencies": {
"rimraf": "^3.0.2",
筆記:
- 你可以隨意呼叫你的腳本,但這
build是慣用的。這些空間會讓我發瘋,因為npm run Rebuild distributable它不起作用。你必須要么參考 like 要么像npm run 'Rebuild distributable'逃避一樣npm run Rebuild\ distributable - 如果您有一個
"files"條目package.json,則不再需要.npmignore. 這意味著“僅打包指定的檔案”,這比必須記住將每個新檔案添加到忽略串列要安全得多。 - 我添加了
rimraf依賴項,這是一種以平臺無關的方式洗掉dist目錄的常用工具。del-cli僅適用于窗戶。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/314048.html
標籤:javascript node.js typescript webpack
