簡體   English   中英

BabelJS 和 Webpack 配置以獲得最大可能的兼容性

[英]BabelJS and Webpack config for maximum possible compatibility

我的網站必須使用可以想象到的最基本的手機瀏覽器,因為我的用戶群是埃塞俄比亞農村兒童,他們使用非常非常基本的手機。 (我正在使用 jquery 來節省手機電池,因為大多數都是“回收的”,二手/三/四手和古老的,而且我非常小心數據成本。)

我正在嘗試設置 Babel + Webpack 以轉換為盡可能低的可支持目標,但我誤解了 Babel 文檔,(例如,我從@babel/preset-env開始並且沒有目標,因為我認為不定位意味着最大兼容性,但這不是 polyfill),並且無法針對我的大量目標手機和瀏覽器進行測試。

  • 下面的配置是否會生成並捆綁 Javascript 將在最大可能的瀏覽器范圍內運行? 有什么辦法讓它更兼容嗎?

  • 我有useBuiltins=usage - 下面的 webpack 配置會檢測到重復導入和樹抖動嗎? 如果不是我需要更改什么,或者我的index.js中的useBuiltins=entryrequire('core-js');require('regenerator-runtime/runtime')會更好嗎?

  • 使用importrequire來導入 bootstrap 會生成比 bootstrap 發行版更大的文件,即使我在 JS 中沒有引用它。 我怎樣才能讓搖樹工作? 我不應該通過 npm 使用 jquery 嗎? 編輯:搖樹只發生在 PROD 構建上,並且似乎正在使用以下配置。

  • 我可以安全地使用最新的 jquery 並依賴 polyfill,而不是 1.12,它存在安全問題,但我正在使用它,因為它適用於更多瀏覽器?

  • 我可以刪除@babel/cli ,因為 webpack 正在運行 babel 嗎? (它有效,我只是想確保我得到了每一盎司的 polyfill 和兼容性,如果更好的話,我很樂意運行 babel CLI。)

  • 還有其他錯過的機會/建議嗎?

(If relevant, I do not need any chunking - this is a simple app and I am caching indefinitely. I am writing this into a Django static folder, and Django + whitenoise are handling filename fingerprinting and HTTP compression. I will at some point add JS 單元測試。我正在為 polyfills 和 tree-shaking 導入 bootstrap JS(盡管 Bootstrap 似乎沒有在搖晃),但是直接從 HTML 加載 bootstrap CSS 以避免在我更新應用程序時緩存未命中。)

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..

更新:我決定不按照@tfr 的建議逐步填充(使用<script type="module".. ),因為對我來說測試最低手機比優化新手機更重要。 如果我在更現代的測試設備上運行 polyfill,這種情況更有可能發生。 也就是說,core-js 聲稱只有在必要時才使用 polyfill,所以我不確定nomodules是否真的會在包大小之外產生影響(我對這項技術的大部分理解是選擇我相信我理解的更多信息) . 我還決定直接從瀏覽器加載 Bootstrap 和 Popper,而不是捆綁。 我正在考慮生成一個vendor.js ,但不確定是否有任何優勢,除了它們可能會在我的包中的 polyfill 之前加載。

非常感謝。

通常最好的方法是同時捆綁雙重(現代瀏覽器和舊版),因此您不必填充現代設備。 看看這個工作 polyfill 示例

這就是你如何為現代瀏覽器加載 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM