terser-webpack-plugin配置导致压缩后JS全局函数无法访问问题
问题描述
遇到Terser配置错误导致页面压缩版本运行崩溃的问题:index.js中存在部分函数声明,需要可被后续动态加载的Bootstrap模态窗口访问。
例如,index.js中有如下方式声明的函数:
function doThis() { }
当用户打开模态窗中的地址表单时,会加载名为address-form.js的独立JavaScript文件,该文件内按钮的onclick处理程序会调用doThis()。index.js未压缩时按钮功能正常,但压缩后会抛出doThis()不存在的错误。
这是作用域问题:压缩后的index.js中可以看到doThis()的声明,但它被包裹在匿名函数作用域内部,无法被全局访问。index.js中还有数百个存在同类作用域问题的函数声明和变量,不希望通过大幅修改该文件解决问题。
尝试将函数声明改为挂载到window的表达式形式后功能正常:
window.doThis = function() { }
但该文件中存在数百个var、const、let变量以及数十个函数声明,逐一修改所有变量的作用域适配压缩规则并不现实。
webpack.config.js配置如下:
const TerserPlugin = require("terser-webpack-plugin") const glob = require('glob') const path = require('path') const webpack = require('webpack') module.exports = { entry: glob.sync('./js/Pages/*.js').reduce((object, element) => { object[path.parse(element).name] = element return object }, {}), output: { filename: '[name].js', path: path.resolve(__dirname, './js/Pages/minified') }, optimization: { minimize: true, minimizer: [ new TerserPlugin({ parallel: true, test: /\.js(\?.*)?$/i, terserOptions: { mangle: false, compress: true, keep_fnames: true, keep_classnames: true, ie8: false, safari10: false, toplevel: false } }) ] }, plugins: [ new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }) ] }
执行的打包命令为:webpack --mode=production --config webpack.config.js
解决方案
最终采用的方案是直接使用terser-cli,编写了对目录下所有文件执行terser压缩的小脚本,可供有需要的人参考:
const fs = require('fs') const path = require('path') const exec = require('child_process').exec; const Terser = require('terser') const srcDir = '../js/Pages' const destDir = '../js/Pages/minified' function minifyPagesDir() { let srcFileNames = fs.readdirSync(srcDir).filter(path => path.match(/\.js$/)) || [] let srcFilePaths = [] let destFilePaths = srcFileNames.map((item, i) => { srcFilePaths[i] = `${srcDir}/${srcFileNames[i]}` return `${destDir}/${item}` }) if (!fs.existsSync(destDir)) fs.mkdirSync(destDir) srcFileNames.forEach((item, i) => { exec( `terser ${srcFilePaths[i]} -c -o ${destFilePaths[i]} --ecma 2021`, (error, stdout, stderr) => { if (error !== null) console.log(`RUHROH: ${error}`, ' stderr: ', stderr); } ) console.log(`Minified '${srcFilePaths[i]}' to '${destFilePaths[i]}'!`) }) console.log('Minification complete!') } minifyPagesDir()
内容的提问来源于stack exchange,提问作者Ringo
相关产品推荐
相关产品推荐

