首页 文章

带有babel-loader的Webpack不会发出有效的es5

提问于
浏览
0

我有一个基于https://github.com/vuejs-templates/webpack-simple/blob/master/template/webpack.config.js的webpack配置它使用vue-loader和babel-loader . 问题是我无法生成ES5代码,因此它可以在最广泛的客户端中运行 .

如果我使用ES2015预设, webpack.optimize.UglifyJsPlugin 无法缩小输出,因为Uglify只能处理ES5(不计算和声分支) . 错误类似于: Unexpected token: punc (() 并出现在多个文件中 .

我可以通过使用 babili-webpack-plugin 解决这个问题,这将缩小ES6代码但速度非常慢 . 但是,当我部署此代码时,我看到报告的错误说 Block-scoped declarations (let, const, function, class) not yet supported outside strict mode 所以我知道他们是老客户窒息ES6代码 .

如何从 babel-loader 获得正确的ES5代码输出?我尝试了多个预设,有或没有 transform-runtime 插件 . 配置如下:

const webpack = require('webpack');
const globEntries = require('webpack-glob-entries');
const _ = require('lodash');
const path = require('path');
const BabiliPlugin = require("babili-webpack-plugin");

const env = process.env.NODE_ENV;

let entries;
if (env === 'production') {
  entries = globEntries('./src/**/vue/*.js');
} else {
  entries = _.mapValues(globEntries('./src/**/vue/*.js'), entry => [entry, 'webpack-hot-middleware/client?reload=true']);
}

module.exports = {
  entry: entries,
  output: {
    path: '/', ///no real path is required, just pass "/"
    publicPath: '/vue',
    filename: '[name].js',
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            scss: 'vue-style-loader!css-loader!sass-loader',
            sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
          },
          // other vue-loader options go here
        },
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          query: {
            presets: ['es2015'],
            plugins: ['transform-runtime'],
          },
        },
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]',
        },
      },
    ],
  },
  resolve: {
    alias: {
      vue$: 'vue/dist/vue.esm.js',
    },
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(), // Enable HMR
    new webpack.NoEmitOnErrorsPlugin(),
  ],
  performance: {
    hints: false,
  },
  devtool: '#eval-source-map',
};

if (env === 'staging' || env === 'production') {
  //module.exports.devtool = env === 'staging' ? '#source-map' : false;
  module.exports.devtool = '#source-map';
  module.exports.output.path = path.resolve(__dirname, './src/v1/parse/cloud/public/vue');
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: `"${env}"`,
      },
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false,
      },
    }),
    // new BabiliPlugin(),
    new webpack.LoaderOptionsPlugin({
      minimize: true,
    }),
  ]);
}

2 回答

  • 2

    这里的答案没有错,但这里有一个不需要.babelrc文件的解决方案 . 此答案适用于独立的webpack.config.js文件 . 我从laravel-mix库的引擎盖下看到了这个答案 .

    module: {
    rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders:{
                        js: {
                            loader: 'babel-loader',
                            options: {                
                                        cacheDirectory: true,
                                        presets: [
                                            ['env', {
                                                'modules': false,
                                                'targets': {
                                                    'browsers': ['> 2%'],
                                                    uglify: true
                                                }
                                            }]
                                        ],
                                        plugins: [
                                            'transform-object-rest-spread',
                                            ['transform-runtime', {
                                                'polyfill': false,
                                                'helpers': false
                                            }]
                                        ]
                                    }
                            },
                        }
                }
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]?[hash]'
                }
            }
    
        ]
    },
    

    我花了一天的时间阅读所有这些无用的博客,省略了babel-loader必须附加到vue-loader的核心概念 .

  • 1

    vue-loader 将使用 babel-loader (如果已检测到)和uses .babelrc by default处理您的 js .

    在当前设置中,当 vue-loader 使用Babel时,您不会将任何选项传递给Babel(意味着Babel不对您的Vue文件使用规则) .

    创建 .babelrc 或自己为 .vue 文件指定 js 加载程序,为其提供选项:

    {
      test: /\.vue$/,
      loader: 'vue-loader',
      options: {
        loaders: {
          js: 'babel?presets[]=es2015' // Pass parameters as options
        }
      }
    }
    

    Babel has an uglify optionenv预设将完全编译为 ES5 . 建议使用此预设以使您的环境保持最新 .

    // .babelrc
    {
      "presets": [
        [ "env", { "uglify": true } ],
        "stage-1" // Or other presets not included with 'env' preset.
      ],
      "plugins": ["transform-runtime"]
    }
    

    您可以添加 es2016es2017 ,以及 stage-4stage-3 等,以确保所有代码都已转换,而不仅仅是ES2015部件,而不是仅使用预设 es2015 .

相关问题