背景: 項目基於原生js,沒用到任何腳手架和框架,但也需要打包壓縮。 項目的js中聲明瞭一些全局變數 供其他js調用。 這時候如果用webpack打包,基於webpack特性,會嵌套一層大函數,會將js中的變數變成局部,不能供其他js調用。 因此棄用了webpack。選用了uglifyjs。 原因: ...
背景:
項目基於原生js,沒用到任何腳手架和框架,但也需要打包壓縮。
項目的js中聲明瞭一些全局變數 供其他js調用。
這時候如果用webpack打包,基於webpack特性,會嵌套一層大函數,會將js中的變數變成局部,不能供其他js調用。
因此棄用了webpack。選用了uglifyjs。
原因:
webpack里也有用到uglifyjs的webpack版:uglifyjs-webpack-plugin。
打包途徑:
打包源文件:dev文件夾下的js文件====>目標文件:js文件夾。
目錄結構
使用:
1、如果是es5 使用uglify-js 官網的預設分支就是這個。
2、如果是es6 使用uglify-es 官網的harmony分支 下載下來就是uglify-es。
uglifyjs官網:https://github.com/mishoo/UglifyJS2
步驟:
首先確認自己電腦有沒有安裝node,這是用node啟動的。
1、下載uglifyjs 這裡我下載的是es版。
npm install uglify-es -D
2、寫一個package.json,下麵的package.json可以下載下來 直接npm i 就省略了第一步了。
scripts裡面是我寫的命令
我想在development下打包後也能調試 用到了sourceMap(映射),
在production下打包壓縮。
我的入口文件 起名了entry.js
{ "name": "ocplayermin", "version": "1.0.0", "description": "ocplayer min version", "main": "entry.js", "scripts": { "build_min": "NODE_ENV=production node entry.js --progress", "build_min_dev": "NODE_ENV=development node entry.js --progress" }, "keywords": [], "author": "", "license": "MIT", "dependencies": {}, "devDependencies": { "uglify-es": "^3.3.9", "uglify-js": "^3.7.4" } }
註意:NODE_ENV在windows下不相容 需要安裝cross-env插件:npm install cross-env --save-dev
安裝完 在 build_min 和 build_min_dev後加上 cross-env 就可以。
3、entry.js代碼
打算把dev文件下的js文件打包到js文件中。
代碼邏輯:
- 1、遍歷dev文件夾下的所有js文件,獲取到文件名和舊路徑。
- 2、生成js文件夾,如果沒有js文件夾 則創建,生成新文件的路徑。
- 3、development下 用UglifyJS.minify壓縮生成sourceMap文件。
- 4、production下 由於development環境下生成了.js.map文件,這裡刪除.js.map,生成.js文件。
遇到的問題:
由於在瀏覽器讀取時,映射 source map讀取的文件需要和js是同一個目錄 因此需要將前端的埠路徑,賦值到.js.map。
例如:地址:127.0.0.1:5500/minversion/index.html;
推薦一款好用的編輯器(用vcode編輯器的open with live server啟動項目,預設埠5500)
讀取前端js路徑:127.0.0.1:5500/minversion/js/xxx.js;
映射生成的路徑也得是127.0.0.1:5500/minversion/js/xxx.js.map;如果是'./js/xxx.js.map'是讀取不到的。
我新建了一個config.json 專門存取常量,我將前端的埠寫在這裡 聲明為:PLUGIN_URL只要修改這個,entry.js就能讀取到。
對source map 不太知道的 可以看官網文檔。
config.json
{"pluginUrl":"http://127.0.0.1:5500/minversion"}
entry.js
const path = require('path'); const fs=require('fs'); const UglifyJS = require("uglify-es");//相容es6 //var UglifyJS = require("uglify-js");//es5 const ORIGIN_PATH='/dev'; const ORIGIN_DIR = '.'+ORIGIN_PATH; // 原目錄 const DESTINATION_PATH='/js'; const DESTINATION_DIR = '.'+DESTINATION_PATH;//打包後的目錄 var PLUGIN_URL="";/*地址*/ PLUGIN_URL=JSON.parse(fs.readFileSync('./config.json','utf-8')).pluginUrl; // 遍歷目錄得到文件信息 function getPath(_path, callback) { let files = fs.readdirSync(_path); files.forEach(function(file){ //判斷文件是否存在 if (fs.statSync(_path + '/' + file).isFile()) { callback(_path, file); } }); } //生成壓縮後的文件 function buildMin (callback) { /*如果不存在min 就會創建min文件夾*/ if ( !fs.existsSync(DESTINATION_DIR) ) { fs.mkdirSync(DESTINATION_DIR); } // 運行 getPath(ORIGIN_DIR, function (_path, file) { let fileName = file.match(/(\S+)(\.\S+)$/)[1]; // 獲得文件名 let oldPath = _path + '/' + file, // 原路徑 newPath = DESTINATION_PATH + '/' + fileName+'.js'; // 新路徑 到不了.js const _code = fs.readFileSync(oldPath, 'utf-8'); callback(newPath,fileName,_code) }); } //刪除文件 function deleteFile(delPath, direct) { delPath = direct ? delPath : path.join(__dirname, delPath) try { /** * @des 判斷文件或文件夾是否存在 */ if (fs.existsSync(delPath)) { fs.unlinkSync(delPath); } else { console.log('inexistence path:', delPath); } } catch (error) { console.log('del error', error); } } if (process.env.NODE_ENV === 'production') { /*生產環境*/ getPath(DESTINATION_DIR, function (_path, file) { //刪除.map文件 if(file.indexOf('.js.map')>-1){ let delp = _path+'/'+file; deleteFile(delp) } })
//打包 buildMin(function(newPath,fileName,_code){ const minCode = UglifyJS.minify(_code,{ compress:{pure_funcs:'console.log'} }).code; fs.writeFileSync('.'+newPath, minCode); }); } if (process.env.NODE_ENV === 'development') { /*開發環境*/
//打包 buildMin(function(newPath,fileName,_code){ var _codeFname = "."+newPath; var _code_file={}; _code_file[_codeFname]=_code; const _minObj = UglifyJS.minify(_code_file,{ sourceMap: { filename:fileName+'.js', url:PLUGIN_URL+newPath+".map",//生成的就是127.0.0.1:5500/minversion/js/xxx.js.map includeSources:PLUGIN_URL+newPath+".map", }, keep_fnames:true, warnings: true, }); fs.writeFileSync('.'+newPath, _minObj.code); fs.writeFileSync('.'+newPath+'.map', _minObj.map); }); }
至此就打包成功啦,可以複製到自己項目中試一下。記得將源文件夾、目標文件夾改成你的項目路徑,還有PLUGIN_URL。