eleven-net-cn / webpack.eleven.net.cn

webpack development guide
https://webpack.eleven.net.cn/
4 stars 1 forks source link

@babel/plugin-transform-runtime #9

Open eleven-net-cn opened 3 years ago

eleven-net-cn commented 3 years ago

https://webpack.eleven.net.cn/content/babel/transform-runtime.html

foreverwang commented 3 years ago

你好看了你的webpack专题文章,收益匪浅,先表示感谢。 但是我在rollup 中用babel7按需引入polyfill时遇到了个问题,想向你请教一下。

问题描述: 打包后的代码包含 require('@babel/runtime-corejs3/core-js/promise') 这样的代码,这在浏览器无法引用到对应文件

问题背景: 使用的按需polyfill方案: @babel/plugin-transform-runtime + corejs3

具体配置:

src/.babelrc

{
    "presets": [
      [
        "@babel/preset-env",
        {
          "modules": false
        }
      ]
    ],
    "plugins": [
        [
          "@babel/plugin-transform-runtime",
          {
            "corejs": {
              "version": 3,
              "proposals": true
            },
            "useESModules": true
          }
        ]
    ]
}

rollup.config.js

import resolve from "@rollup/plugin-node-resolve";
import babel from "@rollup/plugin-babel";
export default {
    input: ["./src/index.js"],
    output: {
      file: "./dist/bundle.js",
      format: "umd", // umd cjs es
      name: "mylib",
    },
    plugins: [
        resolve(),
        babel({ babelHelpers: 'runtime' }),
    ]
};

源码:src/index.js

const a = 1;

const p = new Promise((resolve) => {
    resolve();
})

console.log(a,p)
export const d =  [1,2,3].includes(1);

打包产物:dist/bundle.js

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@babel/runtime-corejs3/core-js/promise'), require('@babel/runtime-corejs3/core-js/instance/includes')) :
    typeof define === 'function' && define.amd ? define(['exports', '@babel/runtime-corejs3/core-js/promise', '@babel/runtime-corejs3/core-js/instance/includes'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.mylib = {}, global._Promise, global._includesInstanceProperty));
}(this, (function (exports, _Promise, _includesInstanceProperty) { 'use strict';

    function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

    var _Promise__default = /*#__PURE__*/_interopDefaultLegacy(_Promise);
    var _includesInstanceProperty__default = /*#__PURE__*/_interopDefaultLegacy(_includesInstanceProperty);

    var _context;

    var a = 1;
    var p = new _Promise__default['default'](function (resolve) {
      resolve();
    });
    console.log(a, p);
    var d = _includesInstanceProperty__default['default'](_context = [1, 2, 3]).call(_context, 1); // export default () => {

    exports.d = d;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
eleven-net-cn commented 3 years ago

@foreverwang

将你的代码编译输出 umd 模块,和你的结果确实不一样,我这边 rollup 编译后代码:

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.LibraryTest = {}));
}(this, (function (exports) { 'use strict';

    var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

    // 省略大段 promise polyfill 代码

    var includes$2 = function (it) {
      var own = it.includes;
      if (it === ArrayPrototype || (it instanceof Array && own === ArrayPrototype.includes)) return includes$4;
      if (typeof it === 'string' || it === StringPrototype || (it instanceof String && own === StringPrototype.includes)) {
        return includes$3;
      } return own;
    };

    var includes$1 = includes$2;

    var includes = includes$1;

    var _context;
    var a = 1;
    var p = new promise(function (resolve) {
      resolve('success');
    });
    console.log(a, p);
    var d = includes(_context = [1, 2, 3]).call(_context, 1);

    exports.d = d;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=library-test.umd.js.map

看你的 rollup 配置,推测是少了 commonjs 模块处理?你加一下试试

import commonjs from '@rollup/plugin-commonjs';
plugins: [
    commonjs(),
    resolve(),
    babel({ babelHelpers: 'runtime' }),
]

推荐你直接使用 library-starter 去创建一个 rollup 编译环境,对比看一下 rollup 使用方面的差异。

foreverwang commented 3 years ago

@ eleven-net-cn
多谢, 确实是缺失commonjs插件导致的,如果只是加上commonjs 的话还有别的问题: image

看上去像是 .babelrc里配置的 plugin-transform-runtime 没有生效,我改成babel.config.js 方式,没问题了 , 太难了,我去研究下babelrc配置的问题

有问题的 .babelrc

{
    "presets": [
      [
        "@babel/preset-env",
        {
          "modules": false
        }
      ]
    ],
    "plugins": [
        [
          "@babel/plugin-transform-runtime",
          {
            "corejs": {
              "version": 3,
              "proposals": true
            },
            "useESModules": true
          }
        ]
    ]
}

问题解决的 babel.config.js

module.exports = {
    presets: [
      [
        '@babel/preset-env',
        {
          modules: false,
        },
      ],
    ],
    plugins: [
      [
        '@babel/plugin-transform-runtime',
        {
          corejs: {
            version: 3,
            proposals: true,
          },
          useESModules: true,
        },
      ]
    ],
  };