0

试图避免 webpacker:compile 删除函数名。尝试过 Terser 甚至 babel-plugin-minify-mangle-names。到现在都没去。

为详细的长解释道歉。

我的设置:带有 gem 'webpacker'、'~> 4.0.7' 的 Rails 5.2

包.json

{
    "name": "myApp",
    "private": true,
    "dependencies": {
        "mjml": "^4.4.1"
    },
    "scripts": {
        "lint": "eslint src",
        "lint:fix": "eslint src --fix",
        "v:patch": "npm version --no-git-tag-version patch",
        "build": "npm run v:patch && webpack -p",
        "start": "webpack-dev-server --open --progress --colors"
    },
    "devDependencies": {
        "@babel/core": "^7.5.5",
        "@babel/preset-env": "^7.5.5",
        "babel-plugin-minify-mangle-names": "^0.5.0",
        "@rails/webpacker": "^4.0.7",
        "babel-loader": "^8.0.6",
        "caniuse-lite": "1.0.30000697",
        "coffeescript": "1.12.7",
        "eslint": "^6.1.0",
        "extract-text-webpack-plugin": "^4.0.0-beta.0",
        "grapesjs": "^0.14.52",
        "grapesjs-mjml": "^0.1.10",
        "grapesjs-navbar": "^0.1.5",
        "grapesjs-preset-webpage": "^0.1.10",
        "html-webpack-plugin": "^3.2.0",
        "mermaid": "^8.2.3",
        "node-sass": "^4.12.0",
        "prop-types": "^15.6.0",
        "webpack": "^4.39.1",
        "webpack-cli": "^3.3.6",
        "webpack-dev-server": "^3.7.2",
        "webpack-merge": "^4.1.1",
        "webpack-node-externals": "^1.7.2"
    }
}

我将 'minify-mangle-names' 添加到babel.config.js,否则与此处的基本示例相同

module.exports = function(api) {
    ...
    return {
    presets: [
        isTestEnv && [
            '@babel/preset-env',
            {
                targets: {
                    node: 'current',
                }
            }
        ],
        plugins: [
            'minify-mangle-names',
            ...

我的 webpack/production.js 文件如下:

process.env.NODE_ENV = process.env.NODE_ENV || 'production'

const TerserPlugin = require('terser-webpack-plugin')

const environment = require('./environment')
const path = require('path');
let plugins = [];

const merge = require('webpack-merge');
module.exports = merge({
    module: {
        rules: [
            {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env'],
                },
            },
        ]
    },
    resolve: {
        alias: {
            'fs': path.resolve('node_modules/grapesjs-mjml/mocks/fs'),
            'uglify-js': path.resolve('node_modules/grapesjs-mjml/mocks/uglify-js'),
        }
    },
    optimization: {
        minimizer: [
            new TerserPlugin({
                test: /\.m?js$/,
                sourceMap: true,
                terserOptions: {
                    keep_fnames: true
                },
            }),
        ],
    },
    target: 'web',
    plugins: plugins,
    externals: {
        'grapesjs': 'grapesjs',
        'jquery': 'jQuery',
    },
}, environment.toWebpackConfig());
console.log(module.exports.optimization.minimizer[0])

如您所见,我在底部添加了一个控制台输出,以测试是否应用了我为 Terser 设置的优化选项。当我运行NODE_ENV=production ./bin/webpack-dev-server(在生产环境中模拟 webpack 服务器)时,它会打印:

TerserPlugin {
  options: {
    test: /\.m?js$/,
    chunkFilter: [Function: chunkFilter],
    warningsFilter: [Function: warningsFilter],
    extractComments: false,
    sourceMap: true,
    cache: false,
    cacheKeys: [Function: cacheKeys],
    parallel: false,
    include: undefined,
    exclude: undefined,
    minify: undefined,
    terserOptions: { output: [Object], keep_fnames: true }
  }
}
...... a bunch of not so important stuff here

WARNING in ./node_modules/mjml-core/lib/index.js 125:23-143
Critical dependency: the request of a dependency is an expression
 @ ./app/javascript/grapesjs-mjml-overrides/components/index.js
 @ ./app/javascript/packs/grapesjs-mjml.js

WARNING in ./node_modules/mjml-core/lib/helpers/mjmlconfig.js 54:13-38
WARNING in ./node_modules/mjml-core/lib/helpers/mjmlconfig.js 70:9-77
WARNING in ./node_modules/mjml-core/lib/helpers/mjmlconfig.js 107:27-48

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets: 
  js/grapesjs-mjml-f0b8e492c6a669470faa.js (1.52 MiB)
  js/grapesjs-mjml-f0b8e492c6a669470faa.js.gz (444 KiB)

WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
Entrypoints:
  grapesjs-mjml (1.52 MiB)
      js/grapesjs-mjml-f0b8e492c6a669470faa.js


WARNING in webpack performance recommendations: 
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/
ℹ 「wdm」: Compiled with warnings.

正如您在顶部看到的控制台输出keep_fnames设置为truefor Terser。我收到一堆警告,但它模拟它编译。

因为我是用 webpack-dev-server 运行这个的,所以没有编译好的文件,所以接下来,我运行rake assets:precompile来模拟真实的现场部署。正如预期的那样,它打印:

** Invoke assets:precompile (first_time)
** Invoke assets:environment (first_time)
** Execute assets:environment
** Invoke environment (first_time)
** Execute environment
** Invoke yarn:install (first_time)
** Execute yarn:install
yarn install v1.13.0
[1/4]   Resolving packages...
success Already up-to-date.
✨  Done in 0.80s.
** Execute assets:precompile
** Invoke webpacker:compile (first_time)
** Invoke webpacker:verify_install (first_time)
** Invoke webpacker:check_node (first_time)
** Execute webpacker:check_node
** Invoke webpacker:check_yarn (first_time)
** Execute webpacker:check_yarn
** Invoke webpacker:check_binstubs (first_time)
** Execute webpacker:check_binstubs
** Execute webpacker:verify_install
** Invoke environment 
** Execute webpacker:compile
Compiling…
Compiled all packs in .../public/packs

太好了,所以它甚至编译了文件。

但是当我查看 public/packs/js 时,我看到了编译的文件。 .map 文件不存在,尽管我在运行时传递sourceMap: trueTerser它并且没有收到任何警告/错误NODE_ENV=production ./bin/webpack-dev-server。其中一个文件是grapesjs-mjml-795c3e00423f5e30c625.js当我打开它时,我看到一个没有函数名的缩小文件:

!function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=f etc. etc.

这几乎就像我做rake assets:precompile 时一样,我的设置被忽略了。

我已经尝试了很多东西。到目前为止,没有任何效果。有任何想法吗?

更新 通过将以下块添加到我的module.exports = merge({.map 文件现在存在。尽管如此,函数名称还是没有运气。输出:{ libraryExport:'default',libraryTarget:'umd',},

4

1 回答 1

1

我遇到了完全相同的问题(Rails 6.0.2 / webpacker 4.2.2)。试图阻止 webpacker 在生产中修改我的类和函数名称,我在我的 production.js 中设置了 terser-webpack-plugin,如下所示:

environment.config.merge({
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          mangle: true,
          keep_classnames: true,
          keep_fnames: true,
          compress: true
        }
      })
    ]
  }
})

没有帮助。名称仍然被破坏。(将最小化设置为 false 没有帮助 - 根本没有缩小。)

经过大量挖掘,我找到了原因:Webpacker 在webpacker/package/environments/production.js. 通过合并配置,minimizer数组被连接起来,两个Terser 函数都被执行了!

解决方案:environment.config.delete('optimization.minimizer')在将您自己的最小化器添加到配置之前添加。

于 2020-03-20T11:36:12.897 回答