经过一个多小时的探索和调试,我相信我已经找出了问题的原因,但仍然需要解决方案。
我的项目的目录结构如下:
/
|- dist/
|- src/
|- plugins/
|- node_modules/
|- webpack.config.js
|- .babelrc
|- ...
plugins
目录包含git子模块,这些子模块引用了我编写的VideoJS插件。这些插件都是各自独立的项目(具有各自的package.json
)。导入和使用这些插件时,请在src/index.js
中执行以下操作:
import videojs from "video.js";
import "./plugins/AutoplayFixPlugin";
videojs("my-player", { plugins: { autoplayFixPlugin: {} } });
根据Node module resolution algorithm,这将:
./
开头,并尝试将模块作为文件加载AutoplayFixPlugin
是目录,并尝试将模块加载为目录index.js
,index.json
或index.node
文件package.json
文件package.json
文件的main
字段,然后加载该文件通过这种方式,导入./plugins/AutoplayFixPlugin
会正确加载./plugins/AutoplayFixPlugin/src/plugin.js
这是问题所在:当我以这种方式导入模块时, 无 的加载程序会运行。它只是导入原始源代码,而Babel从未在我的插件上执行。
我尝试在导入语句中将./plugins/AutoplayFixPlugin
替换为./plugins/AutoplayFixPlugin/src/plugin.js
,但这也没有帮助。我认为子目录中package.json
的存在以某种方式使Webpack(或Babel)绊倒了。
我已经确认删除package.json
会导致Babel在插件文件上按预期运行。重新添加后,Babel停止工作。我尝试将.babelrc
文件添加到插件目录,但这也不起作用。我尝试在插件的本地安装@babel/core
和@babel/preset-env
,但这也不起作用。
由于某些原因,Webpack加载程序在具有package.json
文件的任何子目录中均未运行(或至少Babel未运行)。
我的项目具有以下设置:
webpack.config.js
:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const TerserWebpackPlugin = require("terser-webpack-plugin");
module.exports = (env, argv) => ({
devtool: argv.mode === "development" ? "inline-source-map" : "source-map",
devServer: {
contentBase: "./dist",
host: "0.0.0.0"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
cacheDirectory: true,
cacheCompression: false
}
}
]
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
},
{
test: /\.s(a|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader"
]
},
{
test: /\.(jpg|png|gif|jpeg|svg)$/,
use: [
{
loader: "url-loader",
options: {
limit: 5000
}
},
"img-loader"
]
}
]
},
optimization: {
minimizer: [
new TerserWebpackPlugin({
sourceMap: true,
cache: true,
parallel: true,
terserOptions: {
compress: {
drop_console: true
}
}
})
]
},
performance: {
maxAssetSize: 9e9,
maxEntrypointSize: 9e9
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
new HtmlWebpackPlugin({
template: "./index.html"
})
]
});
.babelrc
:
{
"presets": [
[
"@babel/preset-env",
{
"debug": true,
"include": [
"transform-block-scoping"
]
}
]
]
}
.browserslistrc
:
# Browsers that we support
last 2 versions, not dead, > 1% in US
# Microsoft no longer provides security updates for IE <= 10
ie >= 11
# Apple no longer provides updates for the iPad Mini
ios >= 9
正在运行npx browserslist
,我得到以下输出:
and_chr 71
and_ff 64
and_qq 1.2
and_uc 11.8
android 67
android 4.4.3-4.4.4
baidu 7.12
chrome 72
chrome 71
edge 18
edge 17
firefox 65
firefox 64
ie 11
ie_mob 11
ios_saf 12.0-12.1
ios_saf 11.3-11.4
ios_saf 11.0-11.2
ios_saf 10.3
ios_saf 10.0-10.2
ios_saf 9.3
ios_saf 9.0-9.2
ios_saf 8
op_mini all
op_mob 46
opera 58
opera 57
safari 12
safari 11.1
samsung 8.2
samsung 7.2-7.4
我尤其对ios_saf 9.0-9.2
行(也可以说ios_saf 8
)感兴趣。我的桌上装有运行iOS 9.3.5的iPad Mini,而Safari抛出错误:
SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode.
从错误中可以明显看出,const
关键字未转换为var
。进行调查看起来像there may be two steps to this transformation:const -> let
通过es6.constants
,然后let -> var
通过es6.blockScoping
看node_modules/@babel/preset-env/data/plugin-features.js
,我看到transform-block-scoping
的一行,但是我看不到transform-constants
或类似的一行。看Babel's official list of plugins,也没有constants
插件。只是block-scoping
(将let
转换为var
)
我想知道是否transform-constants
是否已卷入transform-block-scoping
(an idea that seems to be confirmed by their docs),所以我通过启用{{1 }}中的Babel选项:
transform-block-scoping
至少根据调试输出,看起来debug
正在运行。我也只是出于麻烦,将我的@babel/preset-env: `DEBUG` option
Using targets:
{
"android": "4.4.3",
"chrome": "71",
"edge": "17",
"firefox": "64",
"ie": "11",
"ios": "8",
"opera": "57",
"safari": "11.1"
}
Using modules transform: auto
Using plugins:
transform-template-literals { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-literals { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-function-name { "android":"4.4.3", "edge":"17", "ie":"11", "ios":"8" }
transform-arrow-functions { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-block-scoped-functions { "android":"4.4.3", "ios":"8" }
transform-classes { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-object-super { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-shorthand-properties { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-duplicate-keys { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-computed-properties { "android":"4.4.3", "ie":"11" }
transform-for-of { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-sticky-regex { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-dotall-regex { "android":"4.4.3", "edge":"17", "firefox":"64", "ie":"11", "ios":"8" }
transform-unicode-regex { "android":"4.4.3", "ie":"11", "ios":"8", "safari":"11.1" }
transform-spread { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-parameters { "android":"4.4.3", "edge":"17", "ie":"11", "ios":"8" }
transform-destructuring { "android":"4.4.3", "edge":"17", "ie":"11", "ios":"8" }
---> transform-block-scoping { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-typeof-symbol { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-new-target { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-regenerator { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-exponentiation-operator { "android":"4.4.3", "ie":"11", "ios":"8" }
transform-async-to-generator { "android":"4.4.3", "ie":"11", "ios":"8" }
proposal-async-generator-functions { "android":"4.4.3", "edge":"17", "ie":"11", "ios":"8", "safari":"11.1" }
proposal-object-rest-spread { "android":"4.4.3", "edge":"17", "ie":"11", "ios":"8" }
proposal-unicode-property-regex { "android":"4.4.3", "edge":"17", "firefox":"64", "ie":"11", "ios":"8" }
proposal-json-strings { "android":"4.4.3", "edge":"17", "ie":"11", "ios":"8", "safari":"11.1" }
proposal-optional-catch-binding { "android":"4.4.3", "edge":"17", "ie":"11", "ios":"8" }
transform-named-capturing-groups-regex { "android":"4.4.3", "edge":"17", "firefox":"64", "ie":"11", "ios":"8" }
Using polyfills: No polyfills were added, since the `useBuiltIns` option was not set.
更新为以下内容:
block-scoping
即使在此之后, 静止 也没有将.browserslistrc
转换为last 999 versions
。
我还仔细检查了问题是否不是以两种不同的方式来自(排除的)const
文件夹。首先,查看源代码,我发现该错误发生在var
的以下常规区域中(大约72500行):
node_modules
这是我自己的代码。不过,为了确保 100%确定 ,我从main.js
中删除了/***/ "./plugins/AutoplayFixPlugin/src/AutoplayFixPlugin.js":
/*!************************************************************!*\
!*** ./plugins/AutoplayFixPlugin/src/AutoplayFixPlugin.js ***!
\************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var video_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! video.js */ "./node_modules/video.js/dist/video.es.js");
/* harmony import */ var _utilities_Logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../utilities/Logger */ "./utilities/Logger.js");
/* harmony import */ var _utilities_Logger__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_utilities_Logger__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../package.json */ "./plugins/AutoplayFixPlugin/package.json");
var _package_json__WEBPACK_IMPORTED_MODULE_2___namespace = /*#__PURE__*/__webpack_require__.t(/*! ../package.json */ "./plugins/AutoplayFixPlugin/package.json", 1);
/* harmony import */ var _AutoplayFixPlugin_scss__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./AutoplayFixPlugin.scss */ "./plugins/AutoplayFixPlugin/src/AutoplayFixPlugin.scss");
/* harmony import */ var _AutoplayFixPlugin_scss__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_AutoplayFixPlugin_scss__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _components_AutoplayMuteOverlay__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/AutoplayMuteOverlay */ "./plugins/AutoplayFixPlugin/src/components/AutoplayMuteOverlay.js");
const Plugin = video_js__WEBPACK_IMPORTED_MODULE_0__["default"].getPlugin("plugin"); // Default options for the plugin.
const defaults = {
muted: false,
inline: false
};
行。这使我的编译时间从〜2秒增加到〜30秒,无论出于什么原因,我的错误的行号从〜72500更改为〜43600,否则无效。由于以下原因,我的代码在iPad Mini上仍然失败:
exclude
我对调试方法的想法很少。鉴于我要 明确 定位的浏览器不支持,Babel为什么不将webpack.config.js
转换为SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode.
?即使目标已扩展到const
,它仍然没有执行此转换。