Javascript Babel不转换常量(没有加载程序在子目录上运行) 更新
经过一个多小时的探索和调试,我相信我已经找到了问题的原因,但仍然需要一个解决方案 我的项目具有如下目录结构:Javascript Babel不转换常量(没有加载程序在子目录上运行) 更新,javascript,webpack,browser,babeljs,Javascript,Webpack,Browser,Babeljs,经过一个多小时的探索和调试,我相信我已经找到了问题的原因,但仍然需要一个解决方案 我的项目具有如下目录结构: / |- dist/ |- src/ |- plugins/ |- node_modules/ |- webpack.config.js |- .babelrc |- ... plugins目录包含引用我编写的VideoJS插件的git子模块。这些插件都是各自独立的项目(带有自己的package.json)。导入和使用这些插件时,我在src/index.js中执行以下操作: impor
/
|- dist/
|- src/
|- plugins/
|- node_modules/
|- webpack.config.js
|- .babelrc
|- ...
plugins
目录包含引用我编写的VideoJS插件的git子模块。这些插件都是各自独立的项目(带有自己的package.json
)。导入和使用这些插件时,我在src/index.js
中执行以下操作:
import videojs from "video.js";
import "./plugins/AutoplayFixPlugin";
videojs("my-player", { plugins: { autoplayFixPlugin: {} } });
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"
})
]
});
根据协议,这将:
/
开头,并尝试将模块作为文件加载AutoplayFixPlugin
是一个目录,并尝试将模块作为目录加载index.js
、index.json
或index.node
文件package.json
文件package.json
文件的main
字段,并加载该文件/plugins/AutoplayFixPlugin
正确加载/plugins/AutoplayFixPlugin/src/plugin.js
问题是:当我以这种方式导入模块时,我的加载程序中没有一个运行。它只是导入原始的源代码,巴贝尔永远不会在我的插件上执行
我已经尝试在导入语句中将/plugins/AutoplayFixPlugin
替换为/plugins/AutoplayFixPlugin/src/plugin.js
,但这也没有帮助。我认为在子目录中出现package.json
不知何故会让Webpack(或Babel)崩溃
更新2
我已经确认删除package.json
会导致Babel在插件文件上按预期运行。再加回去,巴贝尔就停止工作了。我已经尝试将.babelrc
文件添加到插件目录中,但这也不起作用。我尝试在插件本地安装@babel/core
和@babel/preset env
,但这也不起作用
出于某种原因,网页包加载程序没有在任何包含package.json
文件的子目录中运行(或者至少Babel没有运行)
原职
我的项目有以下设置:
webpack.config.js
:
import videojs from "video.js";
import "./plugins/AutoplayFixPlugin";
videojs("my-player", { plugins: { autoplayFixPlugin: {} } });
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"
]
}
]
]
}
# 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
.browserslistrc
:
{
"presets": [
[
"@babel/preset-env",
{
"debug": true,
"include": [
"transform-block-scoping"
]
}
]
]
}
# 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
我特别感兴趣的是ios\u-saf 9.0-9.2
行(也可以说ios\u-saf 8
)。我桌上有一台运行iOS 9.3.5的iPad Mini,Safari抛出了一个错误:
SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode.
从错误中可以清楚地看出,const
关键字没有转换为var
。做一些调查看起来是这样的:const->let
通过es6.constants
,然后let->var
通过es6.blockScoping
查看node\u modules/@babel/preset env/data/plugin features.js
我看到了一行用于变换块作用域的内容,但我没有看到用于变换常量的类似内容。看看,也没有常量
插件。只需块作用域
(它将let
转换为var
)
我想知道是否transform constants
被卷入了transform block scoping
(),因此我通过启用Babel中的debug
选项查看transform block scoping
是否正在运行:
@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.
至少根据调试输出,看起来块作用域
正在运行。我还将我的.browserslistrc
更新为以下内容:
last 999 versions
即使在这之后,仍然没有将const
转换为var
我还以两种不同的方式仔细检查了问题是否来自(排除的)node\u modules
文件夹。首先,查看源代码,我发现bug发生在main.js
的以下一般区域(大约72500行):
这是我自己的代码。不过,为了100%确定,我从我的webpack.config.js
中删除了exclude
行。这将我的编译时间从~2秒增加到~30秒,无论出于何种原因,我的错误行号从~72500变为~43600,否则没有效果。我的代码在iPad Mini上仍然失败,原因是:
SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode.
关于如何调试这个,我的想法太少了。既然我针对的浏览器显然不支持,为什么巴贝尔不将const
转换为var
?即使目标扩展到最新的999版本
,它仍然没有执行此转换。可能重复@IsaacVidrine,我确实找到了那篇(6个月)的帖子,但它没有回答我的问题。最终,Hitmands说“找出如何将Safari[添加到你的浏览器列表中],我相信它会像预期的那样工作”,olga_babic用她的浏览器列表(看起来不错)回答,Hitmands回答说“那么你肯定应该更深入地了解浏览器列表及其工作原理”。没什么帮助。你看过这个吗@IsaacVidrine不幸的是,这个问题与网页开发服务器添加的常量有关。我的问题在于我自己的代码中的const
(不是NPM依赖项)。尽管如此,我还是尝试在webpack.config.js
中将babel加载程序的exclude
行更新为/node\u模块(?!\/webpack dev server)/
。不幸的是,这并没有解决我的问题。@loganfsmyth因此,让我来看看BabelCroots
,这让我找到了一个非常简单的解决问题的方法。显然,如果子目录中有多个包,则必须使用babel.config.js
文件,而不是.babelrc
文件。我将.babelrc
重命名为babel.config.js
,并添加了一个module.exports=<