【问题标题】:Laravel Mix: Configure Babel for IE11 compatibility (transformations and polyfills)Laravel Mix:为 IE11 兼容性配置 Babel(转换和 polyfills)
【发布时间】:2020-02-28 10:05:51
【问题描述】:

在带有 Laravel-Mix 4 的 Laravel 6 应用程序中,并使用 Vue 预设,我需要编译我的 JavaScript 代码以兼容 IE11。这意味着为缺少的函数添加任何 polyfill,编译箭头函数等等。开箱即用,这还没有完成。

我在resources/js/app.js中的测试代码:

//require('./bootstrap');
let test = [1, 2, [3, 4]];
console.log(
    test.flat().map((x) => 2*x)
);

使用默认配置,laravel mix 似乎不会编译 JavaScript 代码,而只是进行一些格式化。注释保留在编译的输出中。

npm run dev 的结果是:

       Asset      Size   Chunks             Chunk Names
/css/app.css   0 bytes  /js/app  [emitted]  /js/app
  /js/app.js  4.95 KiB  /js/app  [emitted]  /js/app

如何让 Laravel-Mix 使用 Babel 创建兼容 IE11 的源代码?

【问题讨论】:

    标签: laravel babeljs laravel-mix


    【解决方案1】:

    使用 Laravel Mix 启用 Babel 编译,并为 Internet Explorer 使用 polyfills

    第 1 步:安装 Corejs 以获取 polyfills

    按照babel-preset-env 2 的 Babeljs 文档,我们首先需要安装 core-js(其中包含 polyfill):

    $ npm install core-js@3 --save
    

    第二步:配置.babelrc

    在项目根目录下创建.babelrc文件:

    {
        "presets": [
            [
                "@babel/preset-env",
                {
                    "useBuiltIns": "usage",
                    "corejs": {
                        "version": 3,
                        "proposals": false
                    },
                    "targets": {
                        "ie": "11"
                    }
                }
            ]
        ]
    }
    

    现在运行npm run dev,你会发现插入了polyfills,编译了箭头函数等等——你的代码可能只在IE11上运行!

    Laravel-Mix、Babel、IE:一些陷阱

    node_modules 不通过 babel 处理

    使用默认配置,只有项目本身的源代码——而不是它的依赖项——运行 babel 编译步骤。这意味着依赖项中的任何let 或类似的东西都会绊倒旧版浏览器3

    使用 `mix.babel' 有编译文件两次的风险

    laravel mix 文档建议在 Vanilla JS 部分 1 中使用 mix.babel 函数。这似乎做了什么:

    • 如果不存在.babelrc,则通过babel运行指定的文件。
    • 如果存在.babelrc,则正常的混合编译步骤已经使用了babel。使用 mix.babel 会导致编译步骤运行两次。

    有趣的是,两次编译的代码不能在 IE 上运行。一个问题是它将包含对无法处理的 polyfill 的 require() 调用:

    SCRIPT5009: 'require' is undefined
    

    【讨论】:

    • 您的解决方案不适合我。我看不出有什么不同!但是我确实继续使用你不同意的 mix.babel 并且确实我得到了错误 SCRIPT5009: 'require' is undefined。这只是证明我正确地遵循了您的指示,毫无疑问,您的解决方案不起作用。我应该对您的答案投反对票,这样您就不会浪费其他人的时间,但我会等待 1 或 2 次确认我注意到的内容。
    • 注意:即使您的解决方案是正确的,根据我的经验,它也无法与 Laravel Mix 一起使用;即使它被处理,它也只是做其他事情。让它按预期工作的最好方法是使用这个 Laravel Mix 扩展 laravel-mix.com/extensions/polyfill 而不是标准的 babelrc
    【解决方案2】:

    似乎有些人使用mix.babel(),但我相信它与react 更兼容。我有类似的问题,我使用babel-loader@babel/preset-env@babel/polyfill。不得不求助于 polyfill,因为我无法让 core-js 3 按照他们的文档工作。因此,如果有人能够弄清楚如何使其与core-js 3 一起工作。我很乐意学习。并且只安装我的项目似乎需要的东西

    安装:

    npm install babel-loader @babel/preset-env @babel/polyfill --save
    

    Webpack.mix.js

    module: {
        rules: [
          {
            test: /\.m?js$/,
            exclude: /(bower_components)/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: ['@babel/preset-env']
              }
            }
          }
        ]
      }
    

    最后在main/jsapp/js开头导入

    import '@babel/polyfill';
    

    这已经在Laravel 7.x | vue 2.6上测试过

    依赖关系:

    "@babel/polyfill": "^7.10.4",
    "@babel/preset-env": "^7.10.4",
    "babel-loader": "^8.1.0",
    

    注意:我决定从根应用程序中完全删除 .babelrc,可能看起来没有效果,但如果我需要它,我更喜欢将它添加到 config.js

    【讨论】:

      【解决方案3】:

      这就是我设法让我们的网页在 IE11 上运行的方法。 我列出了所有与 Babel 相关的包,尽管其中一些只需要让 Jest 工作。

      package.json

      "devDependencies": {
        "@babel/core": "^7.10.5",
        "@babel/plugin-transform-runtime": "^7.10.5",
        "@babel/preset-env": "^7.10.4",
        "@babel/runtime-corejs3": "^7.10.5",
        "babel-core": "^7.0.0-bridge.0",
        "babel-jest": "^24.9.0",
      },
      

      .babelrc

      {
        "presets": [
          [
            "@babel/preset-env",
            {
              "useBuiltIns": "entry",
              "bugfixes": true,
              "targets": ">0.25%",
              "corejs": {
                "version": 3,
                "proposals": false
              }
            }
          ]
        ],
        "plugins": [
          ["@babel/plugin-transform-runtime", { "corejs": 3 }]
        ]
      }
      

      最后

      app.js

      import './bootstrap';
      import "core-js";
      import Vue from 'vue';
      // ...
      

      我必须说我对useBuiltIns 属性感到困惑,因为不同的文章指向不同的方向。看起来如果您使用"useBuiltIns": "usage",则不需要在app.js 中导入core-js,无论如何我尝试了不同的组合,这一个工作正常。

      根据core-jsreadme,您需要导入它,但我不确定100%。为我指明正确方向的其他资源是这两篇文章:https://www.valentinog.com/blog/preset-env/https://web.dev/serve-modern-code-to-modern-browsers/

      在这个设置之后,我们只需要更新一些 CSS 并且应用程序运行良好。唯一的缺点是vendor.js 文件非常重。我想为支持模块的浏览器创建一个不同的包,但那是另一回事...

      【讨论】:

        猜你喜欢
        • 2020-03-04
        • 2019-02-20
        • 2020-02-21
        • 1970-01-01
        • 2019-09-04
        • 1970-01-01
        • 2019-10-27
        • 1970-01-01
        • 2014-08-20
        相关资源
        最近更新 更多