我正在尝试使用webpack v5.74.0和babel-loader 8.2.5来传输和打包Javascript代码,这些代码必须与微软的WebBrowser控件(即IE 8 /ES 3标准)兼容。特别是,当遇到JS代码时,WebBrowser控件会抛出“预期标识符”错误,其中方法名称也是JS关键字,例如Set.delete()。
下面是一个小测试用例:
项目结构
$ ls -l -R --hide=node_modules
.:
total 266
drwxr-xr-x 1 demo.user 197121 0 Oct 21 17:32 dist/
-rw-r--r-- 1 demo.user 197121 265954 Oct 21 16:56 package-lock.json
-rw-r--r-- 1 demo.user 197121 393 Oct 21 18:09 package.json
drwxr-xr-x 1 demo.user 197121 0 Oct 21 16:06 src/
-rw-r--r-- 1 demo.user 197121 917 Oct 21 17:45 webpack.prod.js
-rw-r--r-- 1 demo.user 197121 145 Oct 21 17:16 xxxbabel.config.json
./dist:
total 1
-rw-r--r-- 1 demo.user 197121 94 Oct 21 17:33 main.js
./src:
total 1
-rw-r--r-- 1 demo.user 197121 94 Oct 21 17:46 main.js
软件包.json:
{
"name": "webpack-test",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"build": "webpack --config=webpack.prod.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.19.3",
"@babel/preset-env": "^7.19.4",
"babel-loader": "^8.2.5",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
}
}
网络包产品js:
const path = require("path");
module.exports = {
entry: {
main: "./src/main.js"
},
mode: "production",
output: {
filename: "[name].js",
path: path.resolve(__dirname, "./dist"),
environment: {
arrowFunction: false // prevent top level arrow IIFE on Webpack 5
},
clean: true // clean output dir before each build
},
module: {
rules: [
{
test: /\.js$/, // transpile JS for older browsers
exclude: /node_modules/, // don't mess with node_modules
use: {
loader: "babel-loader",
options: {
"presets": [
[
'@babel/preset-env', {
targets: {
"ie": "8" // target for IE 8 ES3 for WebBrowser control
},
debug: true
}
]
], // let's us use latest JS features
//"plugins": [ "@babel/plugin-transform-member-expression-literals" ]
}
}
}
]
}
}
输入代码:源代码/main.js
这里我使用Set对象的delete
方法作为示例,请参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
var d = new Set("a", "b", "c");
d["delete"]("a");
console.log("Set has a? "+d.has("a"));
调用webpack使用npm run build
个
$ npm run build
> webpack-test@1.0.0 build
> webpack --config=webpack.prod.js
@babel/preset-env: `DEBUG` option
Using targets:
{
"ie": "8"
}
Using modules transform: auto
Using plugins:
proposal-class-static-block { ie }
proposal-private-property-in-object { ie }
proposal-class-properties { ie }
proposal-private-methods { ie }
proposal-numeric-separator { ie }
proposal-logical-assignment-operators { ie }
proposal-nullish-coalescing-operator { ie }
proposal-optional-chaining { ie }
proposal-json-strings { ie }
proposal-optional-catch-binding { ie }
transform-parameters { ie }
proposal-async-generator-functions { ie }
proposal-object-rest-spread { ie }
transform-dotall-regex { ie }
proposal-unicode-property-regex { ie }
transform-named-capturing-groups-regex { ie }
transform-async-to-generator { ie }
transform-exponentiation-operator { ie }
transform-template-literals { ie }
transform-literals { ie }
transform-function-name { ie }
transform-arrow-functions { ie }
transform-block-scoped-functions { ie < 11 }
transform-classes { ie }
transform-object-super { ie }
transform-shorthand-properties { ie }
transform-duplicate-keys { ie }
transform-computed-properties { ie }
transform-for-of { ie }
transform-sticky-regex { ie }
transform-unicode-escapes { ie }
transform-unicode-regex { ie }
transform-spread { ie }
transform-destructuring { ie }
transform-block-scoping { ie }
transform-typeof-symbol { ie }
transform-new-target { ie }
transform-regenerator { ie }
transform-member-expression-literals { ie < 9 }
transform-property-literals { ie < 9 }
transform-reserved-words { ie < 9 }
proposal-export-namespace-from { ie }
syntax-dynamic-import
syntax-top-level-await
Using polyfills: No polyfills were added, since the `useBuiltIns` option was not set.
asset main.js 94 bytes [compared for emit] [minimized] (name: main)
./src/main.js 90 bytes [built] [code generated]
webpack 5.74.0 compiled successfully in 1940 ms
webpack / babel输出:分发/主.js:
!function(){var a=new Set("a","b","c");a.delete("a"),console.log("Set has a? "+a.has("a"))}();
请注意,a.delete()
调用对IE8无效。它将导致上述“Expected identifier”(预期标识符)错误消息。
预期的输出预期的输出与输入相同,即对delete方法的调用应读取a["delete"]()
。
我试着用他们的REPL页面单独检查babel,那里的代码是正确的:https://babel.dev/repl#?browsers=ie%208&build=&builtIns=false&corejs=false&spec=false&loose=true&code_lz=G4QwTgBAJhC8EDsCmB3CBlJAXAFAIhDwBoI8AjY0gYzwEoBuAKCgDookAbbJfQhoA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=script&lineWrap=true&presets=env%2Cstage-2&prettier=false&targets=&version=7.19.6&externalPlugins=&assumptions=%7B%7D
因此,我认为配置文件不正确,或者webpack/babel-loader配置没有正确传递到babel。我将感谢任何解决这个问题的帮助。
1条答案
按热度按时间dgiusagp1#
所以我找到了解决方案。显然这不是一个巴别塔的问题,而是之后发生的缩小问题。Terser(小型化器)会把代码弄得一团糟。我可以找到正确的选项来防止terser用点符号替换属性访问,文档如下:https://github.com/terser/terser#compress-options
首先,我们需要在webpack.prod.js中包含terser插件:
然后在“module”配置之后附加一个更短的配置:
完整的webpack. prod. js:
然后,输出文件dist/main.js如预期: