前言
客户来了需求:想使用公司的组件包,但组件包的源码不能对其开放,该怎么做呢?
发布后的组件包目录结构如下图所示:
其中,es
文件夹下的js代码皆为esm(ES Module)
模块
lib
文件夹下的js代码皆为cjs(CommonJS)
模块
起初,我是想使用uglify-js
压缩es
文件夹下的代码,但遇到了问题,通过google
以及uglify-js
在github
上的文档说明才知道,uglify-js
不支持压缩es
模块,原文如下所示:
uglify-js
supports JavaScript and most language features in ECMAScript.
For more exotic parts of ECMAScript, process your source file with transpilers like Babel before passing ontouglify-js
.
需要借助Babel
编译ECMAScript
里更复杂的部分(呜呜,es
里的js
文件仅仅只有export default
或export
,再加一些箭头函数,通过uglify-js
压缩后,其code
却为undefined
)
只能暂时放弃压缩es
里的js
文件
解决方法
我选择用uglify-js
压缩lib
文件下的代码,并且lib
文件下的组件可做到按需导入,极大地减少了代码的体积
新建了名为minifyJs
的js
文件,在里面编写压缩并替换源文件的代码,完整代码如下所示:
'use strict';
const fs = require('fs');
const path = require('path');
const UglifyJS = require('uglify-js')
const ROOT_PATH = path.join(__dirname, '../lib');
function readFileList(currentPath) {
const files = fs.readdirSync(currentPath);
files.forEach(file => {
const childPath = path.join(currentPath, file);
const stat = fs.statSync(childPath);
if (stat.isDirectory()) {
readFileList(childPath);
} else {
if(file.endsWith('.js')) {
fs.writeFileSync(childPath, UglifyJS.minify({
"file.js": fs.readFileSync(childPath, "utf8"),
}).code, "utf8", function (error) {
console.log(error)
});
}
}
})
}
readFileList(ROOT_PATH);
const ROOT_PATH = path.join(__dirname, '../lib');
里的__dirname
为Node.js
里的全局变量,表示当前项目的根目录,使用path.join
保证路径地址格式为E:\sf-map\packages\@sf\map-service\lib
,即\
分开stat.isDirectory()
是否为文件夹,若是的话,继续递归调用readFileList
方法fs.writeFileSync(childPath, content, 'utf8', func)
将content
写入至childPath(比如:E:\sf-map\packages\@sf\map-service\lib\request.js)
,若childPath
无该js
文件,则会新增request.js
,若有,则会直接覆盖
切记,该文件内,路径必须用
path.join
,不可使用相对路径,否则minifyJs
的存放位置一旦发生改变,便会出现错误
在package.json
里增加如下scripts
命令:
"scripts": {
"pubmini": "node scripts/minifyJs.js",
}
运行npm run pubmini
即可