Webpack如何构建生产代码以及如何使用它

Gil*_* PJ 87 node.js npm reactjs webpack webpack-dev-server

我是webpack的新手,我发现在生产版本中我们可以减少整体代码的大小.目前webpack构建大约8MB文件,main.js大约5MB.如何减少生产构建中的代码大小?我从互联网上找到了一个示例webpack配置文件,我为我的应用程序配置,然后运行npm run build并开始构建,并在./dist/目录中生成一些文件.

  1. 这些文件仍然很重(与开发版相同)
  2. 如何使用这些文件?目前我正在使用webpack-dev-server来运行该应用程序.

package.json文件

{
  "name": "MyAPP",
  "version": "0.1.0",
  "description": "",
  "main": "src/server/server.js",
  "repository": {
    "type": "git",
    "url": ""
  },
  "keywords": [
  ],
  "author": "Iam",
  "license": "MIT",
  "homepage": "http://example.com",
  "scripts": {
    "test": "",
    "start": "babel-node src/server/bin/server",
    "build": "rimraf dist && NODE_ENV=production webpack --config ./webpack.production.config.js --progress --profile --colors"
  },
  "dependencies": {
    "scripts" : "", ...
  },
  "devDependencies": {
    "scripts" : "", ...
  }
}
Run Code Online (Sandbox Code Playgroud)

webpack.config.js

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var public_dir = "src/frontend";
var ModernizrWebpackPlugin = require('modernizr-webpack-plugin');

module.exports = {
  devtool: 'eval-source-map',
  entry: [
    'webpack-hot-middleware/client?reload=true',
    path.join(__dirname, public_dir , 'main.js')
  ],
  output: {
    path: path.join(__dirname, '/dist/'),
    filename: '[name].js',
    publicPath: '/'
  },
  plugins: [
    plugins
  ],
  module: {
    loaders: [loaders]
  }
};
Run Code Online (Sandbox Code Playgroud)

webpack.production.config.js

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var public_dir = "src/frontend";
var ModernizrWebpackPlugin = require('modernizr-webpack-plugin');
console.log(path.join(__dirname, 'src/frontend' , 'index.html'));

module.exports = {
  devtool: 'eval-source-map',
  entry: [
    'webpack-hot-middleware/client?reload=true',
    path.join(__dirname, 'src/frontend' , 'main.js')
  ],
  output: {
    path: path.join(__dirname, '/dist/'),
    filename: '[name].js',
    publicPath: '/'
  },
  plugins: [plugins],
  resolve: {
    root: [path.resolve('./src/frontend/utils'), path.resolve('./src/frontend')],
    extensions: ['', '.js', '.css']
  },

  module: {
    loaders: [loaders]
  }
};
Run Code Online (Sandbox Code Playgroud)

san*_*eep 58

您可以按照@Vikramaditya的建议添加插件.然后生成生成版本.您必须运行该命令

webpack -p --config ./webpack.production.config.js
Run Code Online (Sandbox Code Playgroud)

-p通知的WebPack生成一个生产版本.您必须更改package.json中的构建脚本以包含生产标志.

  • 好,谢谢.我的下一个疑问是如何运行生产代码?当我运行上面的命令时,它会在dist目录中创建一些文件.确定它编译成功.现在如何使用这些文件?在开发模式中,我使用'npm start'并开始使用它. (5认同)

Vik*_*tya 40

使用这些插件来优化您的生产构建:

  new webpack.optimize.CommonsChunkPlugin('common'),
  new webpack.optimize.DedupePlugin(),
  new webpack.optimize.UglifyJsPlugin(),
  new webpack.optimize.AggressiveMergingPlugin()
Run Code Online (Sandbox Code Playgroud)

我最近开始了解压缩webpack-plugin ,它会压缩你的输出包以减小它的大小.在上面列出的插件列表中添加此项以进一步优化您的生产代码.

new CompressionPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0.8
})
Run Code Online (Sandbox Code Playgroud)

由于CPU使用率过高,建议不要使用服务器端动态gzip压缩来提供静态客户端文件.

  • 此答案不再适用于 webpack 版本 4 (3认同)
  • CommonsChunkPlugin从所有块中提取公共代码并将其放在单独的文件`common.js`中. (2认同)

Gil*_* PJ 37

在观察了这个问题的观众人数后,我决定从Vikramaditya和Sandeep得出答案.

要构建生产代码,首先要创建的是具有优化包的生产配置,例如:

  new webpack.optimize.CommonsChunkPlugin('common.js'),
  new webpack.optimize.DedupePlugin(),
  new webpack.optimize.UglifyJsPlugin(),
  new webpack.optimize.AggressiveMergingPlugin()
Run Code Online (Sandbox Code Playgroud)

然后在package.json文件中,您可以使用此生产配置配置构建过程

"scripts": {
    "build": "NODE_ENV=production webpack --config ./webpack.production.config.js"
},
Run Code Online (Sandbox Code Playgroud)

现在您必须运行以下命令来启动构建

npm run build
Run Code Online (Sandbox Code Playgroud)

根据我的生产构建配置webpack将构建源到./dist目录.

现在您的UI代码将在./dist/目录中可用.配置服务器以将这些文件作为静态资产提供.完成!

  • 你在上一句话中的意思是什么?如何提供这些代码?我知道node.js本身就构建了一个服务器.但是如果我在`./ dist /`目录下有文件后怎么能运行呢? (6认同)
  • 只是注意,在uglifyJS插件的顶部添加-p选项会导致问题,因为它会尝试两次uglify.删除-p cli选项为我解决了这些问题 (6认同)
  • 我仍然不明白如何“设置你的服务器为请求提供这些 UI 代码。你就完成了。”。我明白我们想在这里做什么,但我只是不知道该怎么做 (3认同)
  • 这应该是公认的答案,因为没有人说如何为网站服务**现在您的UI代码将在./dist/目录中提供.设置服务器以提供请求的这些UI代码.你完成了.!** (2认同)
  • 这不适用于 Webpack 4。此外 `mode: 'product' ` 还负责 `NODE_ENV` (2认同)

Siy*_*ang 13

只是自己学习.我将回答第二个问题:

  1. 如何使用这些文件?目前我正在使用webpack-dev-server来运行该应用程序.

您可以只运行"express",而不是使用webpack-dev-server.使用npm install"express"并在项目的根目录中创建一个server.js,如下所示:

var path = require("path");
var express = require("express");

var DIST_DIR = path.join(__dirname, "build");
var PORT = 3000;
var app = express();

//Serving the files on the dist folder
app.use(express.static(DIST_DIR));

//Send index.html when the user access the web
app.get("*", function (req, res) {
  res.sendFile(path.join(DIST_DIR, "index.html"));
});

app.listen(PORT);
Run Code Online (Sandbox Code Playgroud)

然后,在package.json中添加一个脚本:

"start": "node server.js"
Run Code Online (Sandbox Code Playgroud)

最后,运行app:npm run start启动服务器

一个详细的例子可以在以下网址看到:https: //alejandronapoles.com/2016/03/12/the-simplest-webpack-and-express-setup/ (示例代码与最新的软件包不兼容,但它可以工作小调整)

  • 如果你开始学习 nodejs、expressjs 等东西,那么我想告诉你。这个问题是高级问题。它不仅适用于如何运行这些文件。它是关于如何最小化(压缩)生产代码以及如何运行该压缩代码 (2认同)
  • @Arpit 感谢您指出这一点。我对此很陌生。我假设一旦生成了压缩代码,运行方法应该是相同的。 (2认同)

Hay*_*yan 8

您可以使用argv npm模块(通过运行npm install argv --save安装它)来获取webpack.config.js文件中的params,对于生产,您使用-p标志"build":"webpack -p",您可以在webpack.config.js文件中添加条件,如下所示

plugins: [
    new webpack.DefinePlugin({
        'process.env':{
            'NODE_ENV': argv.p ? JSON.stringify('production') : JSON.stringify('development')
        }
    })
]
Run Code Online (Sandbox Code Playgroud)

就是这样.


Kha*_*zam 6

这会对你有所帮助.

plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        // This has effect on the react lib size
        'NODE_ENV': JSON.stringify('production'),
      }
    }),
    new ExtractTextPlugin("bundle.css", {allChunks: false}),
    new webpack.optimize.AggressiveMergingPlugin(),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({
      mangle: true,
      compress: {
        warnings: false, // Suppress uglification warnings
        pure_getters: true,
        unsafe: true,
        unsafe_comps: true,
        screw_ie8: true
      },
      output: {
        comments: false,
      },
      exclude: [/\.min\.js$/gi] // skip pre-minified libs
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]), //https://stackoverflow.com/questions/25384360/how-to-prevent-moment-js-from-loading-locales-with-webpack
    new CompressionPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0
    })
  ],
Run Code Online (Sandbox Code Playgroud)


Put*_*San 5

除了吉尔森 PJ 的回答:

 new webpack.optimize.CommonsChunkPlugin('common.js'),
 new webpack.optimize.DedupePlugin(),
 new webpack.optimize.UglifyJsPlugin(),
 new webpack.optimize.AggressiveMergingPlugin()
Run Code Online (Sandbox Code Playgroud)

"scripts": {
    "build": "NODE_ENV=production webpack -p --config ./webpack.production.config.js"
},
Run Code Online (Sandbox Code Playgroud)

因为它试图两次丑化你的代码。有关更多信息,请参阅https://webpack.github.io/docs/cli.html#production-shortcut-p

您可以通过从 plugins-array 中删除 UglifyJsPlugin 或添加 OccurrenceOrderPlugin 并删除“-p”-flag 来解决此问题。所以一种可能的解决方案是

 new webpack.optimize.CommonsChunkPlugin('common.js'),
 new webpack.optimize.DedupePlugin(),
 new webpack.optimize.UglifyJsPlugin(),
 new webpack.optimize.OccurrenceOrderPlugin(),
 new webpack.optimize.AggressiveMergingPlugin()
Run Code Online (Sandbox Code Playgroud)

"scripts": {
    "build": "NODE_ENV=production webpack --config ./webpack.production.config.js"
},
Run Code Online (Sandbox Code Playgroud)