以下是关于前端项目模块化的实践, 包含以下内容:
搭建 NPM 私有仓库管理源码及依赖;
使用 webpack 打包基础设施代码;
使用 TypeScript 编写可靠类库 (实现中)
本文是关于前端项目模板化的第 2 部分
现状
实际项目远远比示例使用的 myGreeting 复杂, 比如
为了提高可维护性我们将项目折成了许多功能模板;
我们希望使用 Promise 等语法等, 但是顾忌目标环境的支持能力;
可能依赖了多个第三方类库;
为了提高加载速度我们打包时需要进行很多额外工作;
代码压缩;
Tree Shaking(参考文末);
既能运行在 WEB 浏览器, 也能在 NodeJS 中使用;
假设我们有一个工具集项目 myHammer, 包含 base64 转换功能和一个简单版的字典树实现, 项目结构如下:
- busybruce@DESKTOP-B8KJKRS /d/Documents/MyGit/PracticeInNPM/myHammer
- $ tree src/ test/
- src/
- base64.js
- index.js
- TrieFilter.js
- test/
- base64.test.js
- TrieFilter.test.js
- 0 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 https://www.webpackjs.com/ 文档内容多, 网上教程多是关于应用打包, 现整理如下.
本文并非 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 作为目标, 参考 https://webpack.js.org/configuration/output/#output-librarytarget
globalObject: 使用 this 替换默认的 window, 参考 Webpack 4.0.1 | WebWorker
- window is not defined
- #6642 https://github.com/webpack/webpack/issues/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.js
- SGVsbG8gUmF0dHo=
关于 Tree Shaking
略微提及一下 Tree Shaking https://webpack.js.org/guides/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 https://webpack.js.org/guides/tree-shaking/ . 项目所使用源码已发布 https://github.com/jusfr/PracticeInNPM ,jusfrw 原创
来源: https://www.cnblogs.com/Jusfr/p/9551119.html