You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 03:54:05