我有一种情况,我没有正确配置 Terser,这导致我的页面的压缩版本中断。我的问题是我的 index.js 中有一些功能声明。这些声明需要可以在以后加载的 Bootstrap 模式窗口中访问。
例如,在我index.js
有一个这样声明的函数:
function doThis() { }
然后,假设用户在模式窗口中打开一个地址表单,并加载了一个名为“address-form.js”的不同 JavaScript 文件。在这种形式中,有一个带有 onclick 处理程序的按钮,它调用doThis()
. onclick 处理程序位于“address-form.js”中,但能够doThis()
在父 index.js 中访问。当 index.js 未压缩时,该按钮可以正常工作。但是在压缩之后,我得到一个错误doThis()
,说不存在。
我认为这是一个范围界定问题,因为我确实在 中看到了doThis()
声明index.js
,但它似乎被包裹在一堆括号中。我不确定如何使 doThis() 的范围成为顶级窗口。中的数百个函数声明和变量存在相同的范围界定问题index.js
,因此我正在寻找一种解决方案,我不必对庞大的文件进行太多修改。
请注意,如果我将函数声明更改为表达式,它似乎确实有效:
window.doThis = function() {
}
但是,由于文件中有数百个vars
andconst
和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()