Babel не преобразует const (в подкаталоге нет загрузчиков) - PullRequest
0 голосов
/ 11 марта 2019

Обновление

После более чем часа исследований и отладки я считаю, что выяснил причину моей проблемы, но все еще нужно решение.

Мой проект имеет такую ​​структуру каталогов:

/
|- 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: {} } });

В соответствии с алгоритмом разрешения узла это будет:

  1. Убедитесь, что путь начинается с ./ и попробуйте загрузить модуль в виде файла
  2. Признайте, что AutoplayFixPlugin является каталогом, и попробуйте загрузить модуль как каталог
  3. Не удалось найти файл index.js, index.json или index.node
  4. Успешно найти package.json файл
  5. Разобрать файл 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, она по-прежнему не выполняет это преобразование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...