標籤:work 匯出 org 解決 out tin pes env ubuntu
以下是關於前端項目模組化的實踐,包含以下內容:
- 搭建 NPM 私人倉庫管理源碼及依賴;
- 使用 Webpack 打包基礎設施代碼;
- 使用 TypeScript 編寫可靠類庫 (實現中)
本文是關於前端項目模板化的第2部分
現狀
實際項目遠遠比樣本使用的 myGreeting 複雜,比如
- 為了提高可維護性我們將項目折成了許多功能模板;
- 我們希望使用 Promise 等文法等,但是顧忌目標環境的支援能力;
- 可能依賴了多個第三方類庫;
- 為了提高載入速度我們打包時需要進行很多額外工作;
- 代碼壓縮;
- Tree Shaking(參考文末);
- 既能運行在 WEB 瀏覽器,也能在 NodeJS 中使用;
假設我們有一個工具集項目 myHammer,包含 base64 轉換功能和一個簡單版的字典樹實現,項目結構如下:
[email protected] /d/Documents/MyGit/PracticeInNPM/myHammer$ tree src/ test/src/├── base64.js├── index.js└── TrieFilter.jstest/├── base64.test.js└── TrieFilter.test.js0 directories, 5 files
index.js
匯出了項目中的功能模組:
const base64 = require('./base64');const TrieFilter = require('./TrieFilter')module.exports = { base64, TrieFilter,}
如果不打包,單獨發布當前項目到 NPM 倉庫並沒有問題,只是
- 依賴本項目的時候寫法比較糾結,形如
const base64 = require(‘myHammer/src/base64‘)
;
- 可能存在到目標環境的適配問題,如前文所述;
- 目標環境不支援 Promise 等文法等
- 源碼是 CoffeeScript 或者 TypeScript,沒法直接引用
下面使用 Webpack 來解決這些問題。
Webpack 打包基礎類庫
Webpack 文檔內容多,網上教程多是關於應用打包,現整理如下。
本文並非 Webpack 的使用指南,只提及類庫打包,行文時Webpack已更新至4.x 版本。
package.json
需要配置 package.json
的 main
節點供 NodeJS 環境使用。
"main": "src/index.js",
NodeJS 運行環境作了約定,使用 require(‘xxx‘)
時將讀取該配置。
- 避免形如
require(‘myHammer/src/base64‘)
類似的引用完整路徑的寫法
- 如果源碼使用了高版本的語言特性,可以轉譯和打包代碼到形如
dist/inde-es5.js
的路徑,再修改該配置指向該檔案以向下相容
- 使用需要轉譯成 JavaScript 語言同理
在部分 IDE 時我們尋找引用時,往往發現函式宣告有好多處實現,原因就在於代碼轉譯、打包成了很多份,如所示。
webpack.config.js
類庫打包需要對 webpack.config.js
中的 output
進行配置,摘取如下:
output : { library : "hammer", libraryTarget: "umd", globalObject : "this", path : path.join(__dirname, "dist"), filename : "hammer.js",}
其他配置請自行閱讀文檔,完整內容見代碼 webpack.config.js。
libraryTarget
: 為了在瀏覽器和 NodeJS 環境中同時生效,需要使用 umd
作為目標,參考 output-librarytarget
globalObject
: 使用 this
替換預設的 window
,參考 Webpack 4.0.1 | WebWorker window is not defined
#6642
如前文所述,在不考慮語言、版本、目標平台的差異的情況下,直接將源碼發布到 NPM 倉庫,再添加依賴和引用並無問題。在業務日益複雜的情況下,手寫代碼在實現層面直接消除這些差異是無比巨大的工作量,使用 Webpack 讓我們更專註業務本身, Make life easier。
發布到 NPM 和使用依賴
在完成了具體業務後,我們打包項目並發布到私人 NPM 倉庫
webpack --mode development # 視具體需求npm publish --registry http://ubuntu-17:4873 # --force
在 myDemo 項目中我們添加引用
yarn add myHammer --registry http://ubuntu-17:4873
修改 index.js
如下:
const myGreeting = require('myGreeting');const {base64} = require('myHammer');(function () { let greeting = myGreeting('Rattz'); console.log(base64.encode(greeting));})();
運行起來
$ node index.jsSGVsbG8gUmF0dHo=
關於 Tree Shaking
略微提及一下 Tree Shaking ,簡單地說 Tree Shaking 通過不引用沒有依賴的代碼,能有效縮減打包後的檔案大小。
舉例來說,我們使用了 ES2016 的文法,希望最後編譯在 ES2015 環境使用。這裡有若干種可行方案,其中一種是
- 使用 babel 全家桶包含
babel-cli, babel-core, babel-loader, babel-preset-env
;
- 添加 .babelrc 檔案寫入內容
{"presets":["env"]}
;
- 在入口代碼的首行使用
require(‘babel-polyfill‘);
babel 進行文法轉換,補丁檔案進行對低版本 ES2015 的適配,該方案中 babel-polyfill
被完整引用, 打包完成後佔用120k 左右大小,往往比業務代碼還多。
Tree Shaking 即為解決該問題而來,比如某模板同時提供了加法和減法,而我們只依賴了加法方法,如果打包工具支援 Tree Shaking,就能在打包時剔除掉未使用的減法相關代碼。
Webpack 提供了相關支援,見於 Tree Shaking - webpack。
項目所使用源碼發行 github,jusfrw 原創
前端項目模組化的實踐2:使用 Webpack 打包基礎設施代碼