Обновление
После более чем часа исследований и отладки я считаю, что выяснил причину моей проблемы, но все еще нужно решение.
Мой проект имеет такую структуру каталогов:
/
|- 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: {} } });
В соответствии с алгоритмом разрешения узла это будет:
- Убедитесь, что путь начинается с
./
и попробуйте загрузить модуль в виде файла
- Признайте, что
AutoplayFixPlugin
является каталогом, и попробуйте загрузить модуль как каталог
- Не удалось найти файл
index.js
, index.json
или index.node
- Успешно найти
package.json
файл
- Разобрать файл
package.json
для его поля main
и загрузить этот файл
Таким образом, импорт ./plugins/AutoplayFixPlugin
правильно загружает ./plugins/AutoplayFixPlugin/src/plugin.js
Вот проблема: когда я импортирую модуль таким образом, запускаются none моих загрузчиков. Он просто импортирует необработанный исходный код, и Babel никогда не выполняется на моем плагине.
Я пытался заменить ./plugins/AutoplayFixPlugin
на ./plugins/AutoplayFixPlugin/src/plugin.js
в своем операторе импорта, но это тоже не помогло. Я думаю, что наличие package.json
в подкаталоге как-то отключает Webpack (или Babel).
Обновление 2
Я подтвердил, что удаление package.json
заставляет Babel работать должным образом с файлами плагинов. Добавляя его обратно, Бабель перестает работать. Я попытался добавить файл .babelrc
в каталог плагинов, но это также не работает. Я попытался установить @babel/core
и @babel/preset-env
локально на плагин, но это также не работает.
По какой-то причине загрузчики Webpack не работают (или, по крайней мере, Babel не работает) ни в одном подкаталоге, в котором есть файл package.json
.
Оригинальный пост
У меня есть следующие настройки для моего проекта:
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
). У меня на столе iPad Mini под iOS 9.3.5 и Safari выдает ошибку:
SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode.
Из ошибки видно, что ключевое слово const
не преобразуется в var
. Выполнение какого-либо исследования выглядит так: может быть два шага для этого преобразования : const -> let
через es6.constants
, затем let -> var
через es6.blockScoping
Глядя на node_modules/@babel/preset-env/data/plugin-features.js
Я вижу строку для transform-block-scoping
, но не вижу такой строки для transform-constants
или подобного. Глядя на официальный список плагинов Babel , также нет никакого плагина constants
. Просто block-scoping
(который преобразует let
в var
)
Я подумал, что, может быть, transform-constants
был свернут в transform-block-scoping
( идея, которая, кажется, подтверждается их документами ), поэтому я посмотрел, запускается ли transform-block-scoping
вообще включение опции debug
в Babel:
@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
.
Я также дважды проверил, что проблема не связана с (исключенной) папкой node_modules
двумя различными способами. Сначала, глядя на исходный код, я увидел, что ошибка возникает в следующей общей области main.js
(около 72500):
/***/ "./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
};
Это мой собственный код. Тем не менее, чтобы быть уверенным 100% , я удалил строку exclude
из моего webpack.config.js
. Это увеличило время моей компиляции с ~ 2 секунд до ~ 30 секунд, по какой-то причине изменило номер строки моей ошибки с ~ 72500 до ~ 43600, и в остальном ничего не дало. Мой код все еще не работает на iPad Mini из-за:
SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode.
У меня мало идей для отладки этого. Почему Babel не конвертирует const
в var
, учитывая, что браузеры, на которые я нацеливаюсь , явно не поддерживают это? Даже если цель увеличена до last 999 versions
, она по-прежнему не выполняет это преобразование.