Webpack、IE8和ES6模块

6
最近的webpack版本不支持IE8。我已经尝试了1.12.12版本(我认为这是最后一个支持IE8的版本),但仍然会从无法模拟的Object.defineProperty中得到错误。

https://github.com/webpack/webpack/issues/2085

什么是最后一个支持IE8的webpack版本?它是否能够使用ES6模块?

webpack.config.js:

var webpack = require("webpack");
var es3ifyPlugin = require('es3ify-webpack-plugin');
var productionPlugin = new webpack.DefinePlugin({
    'process.env': {
        'NODE_ENV': JSON.stringify('production')
    }
});
var devPlugin = new webpack.DefinePlugin({
    "process.env": {
        NODE_ENV: JSON.stringify("dev")
    }
});

module.exports = {
    entry: {
        assessment: "./src/aaa/app.js"
    },
    //devtool: "source-map",
    output: {
        path: "../AAA/wwwroot/js",
        filename: "[name].bundle.js",
        publicPath: "/"
    },
    resolve: {
        extensions: ["", ".js"]
    },
    module: {
        preLoaders: [
            {
                test: /\.js$/,
                loader: "eslint-loader",
                exclude: "node_modules"
            }
        ],
        loaders: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: "babel-loader"
            },
            {
                // todo: move less compiling to web project 
                test: /\.less$/,
                loader: "style-loader!css-loader!less-loader",
                exclude: "node_modules"
            },
        ]
    },
    devServer: {
        historyApiFallback: true,
        inline: true,
        proxy: {
            "/api": {
                "target": {
                    host: "localhost",
                    protocol: "http:",
                    port: "58211",
                },
                changeOrigin: true,
                pathRewrite: { "^/api": "" }
            }
        },
        publicPath: "/assets/"
    },
    plugins: [
        new es3ifyPlugin(),
        new webpack.optimize.CommonsChunkPlugin({
            name: "vendor",
            minChunks: isExternal
        }),
        productionPlugin
        //devPlugin
    ]
}

function isExternal(module) {
    var userRequest = module.userRequest;

    if (typeof userRequest !== "string") {
        return false;
    }

    return userRequest.indexOf("node_modules") >= 0;
}

转译后的代码如下:

exports.test = '123';

webpackJsonp([1, 0], [

  function (module, exports, __webpack_require__) {

    'use strict';

    var _imported = __webpack_require__(1);


    alert('test ' + _imported.test);

    function(module, exports) {

        "use strict";

        Object.defineProperty(exports, "__esModule", {
            value: true
        });
        var test = exports.test = 123;

      }
  ]);

1.13 版本适合你吗?从相关问题的链接可以看出,这个版本或许能在 IE8 上运行。 - dotcs
有趣的是...从这篇在medium上的博客文章中,我认为应该有选项可以让webpack运行 - 除非应用程序代码中使用了getter/setter。这篇文章是在四月份写的,所以我认为当时的当前版本至少应该可以工作。 - dotcs
嗨,是的,我已经删除了所有代码并安装了1.13.2。生成的捆绑包可以在其他浏览器中工作,但在ie8中不行。代码只是 alert("Hello world"); 错误是 SCRIPT445:对象不支持这个操作sockjs.min.js(3,13318)。我相当确定这是 Object.defineProperty 失败。 - Tom
你能把你正在使用的模块代码和webpack代码添加到问题中吗?在我的测试中,我没有看到类似的东西。 - Alexander O'Mara
1
感谢您的建议,最小化示例是一个好主意,让我成功地使用webpack 1.13.0在IE8中构建了“Hello World”的生产版本。上述提到的sockjs错误只与webpack-dev-server有关,显然我不需要在IE8中使用它。它也可能适用于较新的webpack(1.X),因为我在那里同时遇到了一些问题。 - Tom
显示剩余6条评论
1个回答

1
问题在于Babel默认情况下如何翻译ES2015代码。在默认模式(非松散模式)中,它使用Object.defineProperty,但可以通过使用松散模式进行配置。
// webpack.config.js
module: {
   loaders: [
     {
       test: /\.js$/,
       loader: 'babel-loader',
       exclude: /node_modules/,
       query: {
         presets: [ ['es2015', {"loose": true}] ]
       }
     }
   ]
 }

这将导致以下编译代码:

/* 0 */
/***/ function(module, exports, __webpack_require__) {

    'use strict';

    var _imported = __webpack_require__(1);

    var _imported2 = _interopRequireDefault(_imported);

    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

    console.log('test ' + _imported2.default);

/***/ },
/* 1 */
/***/ function(module, exports) {

    "use strict";

    exports.__esModule = true;
    var test = 123;

    exports.default = test;

/***/ }
/******/ ])

旧答案

从讨论中得知,这个问题已经解决:

1.13.0于2016年4月15日发布。所以看起来应该可以工作。您确定您没有在自己的应用程序代码中使用getter/setter吗?也许您可以创建一个超级简单的示例,只包含一个hello world样本代码,并尝试使用1.13版本创建一个构建。所创建的代码不应该使用Object.defineProperty


虽然上面的配置对于没有模块的“Hello World”可以正常工作,但是一旦我引入模块,就会从webpack生成的代码中得到这行代码Object.defineProperty(exports, "__esModule", {value: true});的错误。如果您有一个适用于IE8的工作设置,能否分享一下? - Tom
在使用webpack 1.13的绝对最小设置中,不会引入Object.defineProperty。请参见代码和已编译的bundle.js - dotcs
1
谢谢。这表明它可以使用require(),但不能使用import(es6模块)。 - Tom
但这来自于 Babel,而不是 Webpack:https://babeljs.io/docs/plugins/transform-es2015-modules-commonjs/ - dotcs
1
我应该补充说明,构造export * from仍将生成使用Object.defineProperty的代码,但可以避免这种情况。 - Tom
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接