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 (()并且发生在多个文件中。

我可以通过使用 which 来解决这个问题,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,
    }),
  ]);
}
4

2 回答 2

4

vue-loader将处理您的jswith babel-loader(如果检测到),并默认使用.babelrc.

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

为文件创建.babelrc或指定js加载器,.vue为它提供选项:

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

Babel的env预设有一个uglify可以完全编译为ES5的选项。建议使用此预设,以使您的环境保持最新。

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

除了只使用预设之外es2015,您还可以添加es2016and es2017, 以及stage-4,stage-3等来确保您的所有代码都被转换,而不仅仅是 ES2015 部分。

于 2017-08-14T13:06:51.743 回答
1

这里的答案已经没有问题了,但这里是一个不需要 .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 的核心概念。

于 2018-03-30T20:30:07.763 回答