Конфигурация BabelJS и Webpack для максимально возможной совместимости

Мой веб-сайт должен работать с самыми простыми телефонными браузерами, которые только можно вообразить, потому что моя база пользователей - это сельские эфиопские дети с очень, очень простыми телефонными трубками. (Я использую jquery для экономии заряда батареи телефона, так как большинство из них «переработано», второе / третье / четвертое руки и старые, и я очень осторожен с затратами на передачу данных.)

Я пытаюсь настроить Babel + Webpack для транспиляции для минимально возможной поддерживаемой цели, но я неправильно понимаю документы Babel (например, я начал с @babel/preset-env и без целей, поскольку я предполагал, что отсутствие таргетинга означает максимальную совместимость, но это не t polyfill) и не могу протестировать на моем огромном количестве целевых телефонов и браузеров.

  • Будет ли приведенная ниже конфигурация создавать и связывать Javascript, который будет работать в максимально возможном диапазоне браузеров? Есть ли способ сделать его более совместимым?

  • У меня useBuiltins=usage - будет ли конфигурация веб-пакета ниже обнаруживать повторяющийся импорт и дрожание дерева? Если нет, то что мне нужно изменить, или было бы лучше useBuiltins=entry и require('core-js');require('regenerator-runtime/runtime') в моем index.js?

  • Использование import или require для импорта начальной загрузки создает файл большего размера, чем дистрибутив начальной загрузки, хотя я не упоминаю об этом в JS. Как я могу заставить работать дрожание деревьев? Не следует ли мне использовать jquery через npm? РЕДАКТИРОВАТЬ: встряхивание дерева происходит только в сборках PROD и, похоже, работает с приведенной ниже конфигурацией.

  • Могу ли я безопасно использовать последнюю версию jquery и полагаться на полифиллинг, а не на 1.12, у которого есть проблемы с безопасностью, но я использую, поскольку он работает в гораздо большем количестве браузеров?

  • Могу ли я удалить @babel/cli, так как в webpack запущен babel? (Это работает, я просто хочу быть уверенным, что получаю максимум полифилов и совместимости, и если будет лучше, буду рад запустить babel CLI.)

  • Есть ли другие упущенные возможности / рекомендации?

(Если уместно, мне не нужны фрагменты - это простое приложение, и я кэширую на неопределенный срок. Я записываю это в статическую папку Django, а Django + whitenoise обрабатывает отпечатки имен файлов и HTTP-сжатие. В какой-то момент я добавлю Модульные тесты JS. Я импортирую JS начальной загрузки для полифилов и встряхивания деревьев (хотя Bootstrap, похоже, не дрожит), но загружаю CSS начальной загрузки непосредственно из HTML, чтобы избежать промахов в кеше при обновлении приложения.)

packages.json:

{
  ...
  "scripts": {
    "start": "webpack-dev-server --open --mode development",
    "build": "webpack --mode production",
  },
  "devDependencies": {
    "@babel/cli": "^7.10.1",
    "@babel/core": "^7.10.2",
    "@babel/plugin-proposal-class-properties": "^7.10.1",
    "@babel/preset-env": "^7.10.2",
    "axios": "^0.19.2",
    "babel-loader": "^8.1.0",
    "bootstrap": "^4.4.1",
    "jquery": "^1.12.4",  // insecure old version but more compatible
    "popper.js": "^1.16.1",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.11.0"
  },
  "dependencies": {
    "@babel/polyfill": "^7.10.1",
    "core-js": "^3.6.5"
  }
}

.babelrc:

{
  "presets": [
    [
      "@babel/env",
      {
        "targets": "cover 100%",
        "useBuiltIns": "usage",
        "corejs": "3.6.5"
      }
    ]
  ],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}

webpack.config.js:

const path = require('path');

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  },
  output: {
    filename: 'app.js',
    publicPath: "/static/",
    path: path.join(__dirname, '../djangoproj/app/static/app')
  },
  devServer: {
    writeToDisk: true, // Django serves the content
  }
};

index.js:

import $ from 'jquery';
import bootstrap from 'bootstrap'
import popper from 'popper.js'
import {Controller} from './controller';

$(document).ready(function() {
  const app = new Controller()
})

controller.js:

import {View} from './view';
import {ActivityStore, ElementStore} from './store';
import {Api} from './api';

export class Controller {
  constructor() {
    this.state = {}
    this.api = new Api(config)

// and so on..

Обновление: я решил не использовать полифилы (с использованием <script type="module" ..), как @tfr рекомендует ниже, поскольку для меня важнее тестировать самые низкие телефоны, чем оптимизировать новые телефоны. Это более вероятно, если я запускаю полифилы на своих более современных тестовых устройствах. Тем не менее, core-js утверждает только полифил, если это необходимо. , поэтому я не уверен, действительно ли nomodules имеет значение, помимо размера пакета (я очень понимаю эту технологию, выбирая, какой части информации я доверяю своему пониманию большего). Я также решил загрузить Bootstrap и Popper прямо из браузера, а не в комплекте. Я собираюсь создать vendor.js, но не уверен, что есть какие-то преимущества, за исключением, возможно, того, что они загрузятся до полифиллов в моем пакете.

Огромное спасибо.


person Chris    schedule 09.06.2020    source источник
comment
Почему бы просто не работать в строгом ES5? Это может немного смущать, но es5 по-прежнему отлично работает js, и es6 не так много, что es5 не может.   -  person admcfajn    schedule 09.06.2020
comment
Спасибо, именно так я и начал, ручное полифиллинг, но, несмотря на то, что это базовое, довольно простое приложение jquery, данные немного сложны, и это сразу был классический старый комок JS-кода, поэтому я хочу использовать структурированную архитектуру (магазины, модели, похожий на сагу контроллер и представление), которые с помощью импорта, классов и стрелочных функций делают намного лучше! Я также надеюсь, что смогу использовать более безопасную версию jquery, и автоматические полифиллы будут более надежными, чем исследования и испытания. Также я написал ES2016 так долго, что случайно использую современный синтаксис и не улавливаю его на своих современных тестовых устройствах.   -  person Chris    schedule 09.06.2020
comment
Парень, я рад быть поздним последователем ... между var & let и традиционными и стрелочными функциями так много нюансов, что я просто пытаюсь брать небольшие куски и постепенно переходить ... сделал много es6 для проекта vue в 2016/17 году, вот ссылка на некоторые из моих лучших es5, я считаю, что шаблон, который он использует, действительно удобен для предотвращения js-hairballs github.com/kanopi/wpqjx/blob/blob/blob/blob/blob/blob задумано как обещание в случае, если это поможет. & удачи!   -  person admcfajn    schedule 10.06.2020


Ответы (1)


Обычно лучшим способом было бы объединить два (современный браузер и устаревшие версии) в одно и то же время, чтобы вам не приходилось полифилить современные устройства. Взгляните на этот пример рабочего полифилла.

Вот как вы можете загрузить пакет es6 для современного браузера и пакет es5 для устаревшего браузера:

  <!-- main bundle -->
  <script type="module" src="/assets/scripts/main.js"></script>
  <!-- polyfilled legacy browser -->
  <script nomodule src="/assets/scripts/main.legacy.js" defer="defer"></script>

И вот главный ответ на ваш вопрос:

Babel Config
============

const legacy = {
  presets: [
    ["@babel/preset-env", {
      targets: {
        browsers: [
          "> 1% in ET", // make sure its the right country code
          "ie >= 6",
          "not dead"
        ]
      },
      useBuiltIns: "usage",
      corejs: 3,
    }]
  ],
  plugins: [
    "@babel/plugin-syntax-dynamic-import",
    "transform-eval"
  ],
  comments: false,
  cacheDirectory: path.join(CACHE_PATH, 'babel-loader')
};


Webpack Config
==============

 const prod = {
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js$/,
        exclude: [
          /node_modules/
        ],
        use: {
          loader: 'eslint-loader',
        },
      },
      {
        test: /\.js$/,
        exclude: [
          /node_modules/
        ],
        loader: "babel-loader",
        options: babelConfig
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.json'],
  }
};

snippets from https://github.com/unic/darvin-webpack-boilerplate/blob/master/webpack/settings/javascript-legacy/index.js
person tfrei    schedule 09.06.2020
comment
Я действительно рекомендую использовать рабочий шаблон с двумя веб-пакетами, например darvin.dev, и настроить параметры. - person tfrei; 10.06.2020
comment
nomodule отличное предложение, спасибо. Нужен ли мне @babel/plugin-syntax-dynamic-import для WebPack 4? Чем transform-eval помогает? (Моими клиентами будет этот самый низкий 1% браузеров.) Как мне создать обе сборки с помощью одной команды npm? Огромное спасибо! - person Chris; 10.06.2020
comment
полнофункциональный современный шаблон с двойным устаревшим браузером займет у вас недели без опыта. 1) установить Дарвина 2) настроить шаблон, чтобы увидеть демонстрационные файлы 3) попытаться понять различные сборки github.com/unic/darvin-webpack-boilerplate/blob/master/.cli/ вы можете сэкономить эти огромные усилия . важно установить правильную настройку в конфигурации babel в @ babel / preset-env.targets.browser babeljs.io/docs/en/6.26.3/babel-plugin-transform-eval см. пример -› in: es6 стрелочная функция out: es5 func - person tfrei; 10.06.2020
comment
Я не думаю, что этот плагин работает? github.com/babel/babel/issues/7250 удален из core-js github.com/babel/babel/pull/7262/files - person Chris; 12.06.2020
comment
в настоящее время он работает над различными крупными проектами - person tfrei; 12.06.2020
comment
Я не сомневаюсь, что эта проблема заключается в том, что основная команда Babel утверждает, что она не могла работать с 2015 года, если вообще работала, но это было так, потому что Babel - это магия, а не наука. Я начинаю понимать, почему документы такие непонятные, и я не получаю ответов - единственный человек, который это понимает, живет в пещере, накладывает заклинания и разговаривает с духами ... - person Chris; 12.06.2020
comment
вы слишком академично думаете. не заморачивайтесь с формой отвертки, затяните винты. кстати, ваш комментарий относится ко всей экосистеме NPM, количество зависимостей беспорядок - person tfrei; 13.06.2020