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


93

我是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" : "", ...
  }
}

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]
  }
};

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]
  }
};

1
您找到最后一个问题的答案了吗?“如何使用这些文件?目前我正在使用webpack-dev-server运行该应用程序。”
兰迪

4
在使用webpack之前,互联网要好得多,只看这个问题和答案。
兰迪L

Answers:


65

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

webpack -p --config ./webpack.production.config.js

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


6
好,谢谢。我的下一个疑问是如何运行生产代码?当我运行以上命令时,它将在dist目录中创建一些文件。好,编译成功。现在如何使用这些文件?在开发模式下,我使用了“ npm start”并启动了它。
Gilson PJ

如果你去你的src/server/bin/server。然后,您可以弄清楚它是如何提供文件的,甚至可以对其进行更改。我认为它将要做的是运行webpack来构建文件,然后为它们提供服务。看一下这个文件的代码。
sandeep


@GilsonPJ您是否知道如何使用这些UI文件?
兰迪

您需要先使用npm install webpack
Peter Rader

43

在观察到这个问题的观众数量之后,我决定总结Vikramaditya和Sandeep的答案。

要生成生产代码,您首先需要创建的是带有优化包的生产配置,例如,

  new webpack.optimize.CommonsChunkPlugin('common.js'),
  new webpack.optimize.DedupePlugin(),
  new webpack.optimize.UglifyJsPlugin(),
  new webpack.optimize.AggressiveMergingPlugin()

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

"scripts": {
    "build": "NODE_ENV=production webpack --config ./webpack.production.config.js"
},

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

npm run build

按照我的生产构建配置,webpack会将源构建到./dist目录。

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


7
您最后一句话是什么意思?如何提供这些代码?我知道node.js会自己构建服务器。但是在./dist/目录中保存文件后如何运行?
newguy

6
请注意,在uglifyJS插件顶部添加-p选项会导致问题,因为它尝试两次uglify。删除-p cli选项已为我解决了这些问题
timelf123 '16

无法将“ NODE_ENV”识别为内部或外部命令,可操作程序或批处理文件。
安东·杜赞科

2
这应该是公认的答案,因为没有人说过如何服务该网站现在,您的UI代码将在./dist/目录中可用。设置服务器以为请求提供这些UI代码。就完成了!
jperelli

2
我仍然不知道如何“将服务器设置为为请求提供这些UI代码。您已完成。”。我了解我们想在这里做什么,但我只是不知道该怎么做
Randy

42

使用以下插件优化您的生产版本:

  new webpack.optimize.CommonsChunkPlugin('common'),
  new webpack.optimize.DedupePlugin(),
  new webpack.optimize.UglifyJsPlugin(),
  new webpack.optimize.AggressiveMergingPlugin()

最近,我了解了compression-webpack-plugin ,它将您的输出包gzip 压缩以减小其大小。还要在上面列出的插件列表中添加此代码,以进一步优化您的生产代码。

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

不建议使用服务器端动态gzip压缩来提供静态客户端文件,因为这会占用大量CPU。


1
“ common.js”部分对commonschuckplugin做了什么?该插件是我最难掌握的。
Echiban '16

2
CommonsChunkPlugin从所有块中提取通用代码并将其放在单独的文件中common.js
Vikramaditya

3
此答案不再适用于Webpack版本4
Dennis,

20

自己学习。我将回答第二个问题:

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

除了使用webpack-dev-server之外,您还可以运行“ express”。使用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);

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

"start": "node server.js"

最后,运行应用程序:npm run start启动服务器

可以在以下位置查看详细示例:https : //alejandronapoles.com/2016/03/12/the-simplest-webpack-and-express-setup/ (示例代码与最新软件包不兼容,但可以使用进行细微调整)


2
如果您开始学习nodejs,expressjs等内容,那么我想告诉您。这个问题是高级问题。不仅用于如何运行这些文件。它用于如何最小化(压缩)生产代码以及如何运行压缩的代码
Arpit,

1
@Arpit感谢您指出这一点。我对此很陌生。我假设一旦生成压缩代码,运行方法就应该相同。
思远姜

9

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

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

就是这样。


1
process.argv.indexOf('-p') != -1
改为

@AjaxLeung:您必须argv在webpack配置文件中添加以下内容:const argv = require('argv');
kadam

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$/]), ///programming/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
    })
  ],

5

除了Gilson PJ答案:

 new webpack.optimize.CommonsChunkPlugin('common.js'),
 new webpack.optimize.DedupePlugin(),
 new webpack.optimize.UglifyJsPlugin(),
 new webpack.optimize.AggressiveMergingPlugin()

"scripts": {
    "build": "NODE_ENV=production webpack -p --config ./webpack.production.config.js"
},

导致它尝试两次使您的代码丑陋。有关更多信息,请参见https://webpack.github.io/docs/cli.html#production-shortcut-p

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

 new webpack.optimize.CommonsChunkPlugin('common.js'),
 new webpack.optimize.DedupePlugin(),
 new webpack.optimize.UglifyJsPlugin(),
 new webpack.optimize.OccurrenceOrderPlugin(),
 new webpack.optimize.AggressiveMergingPlugin()

"scripts": {
    "build": "NODE_ENV=production webpack --config ./webpack.production.config.js"
},

2

如果在webpack.dev.config和webpack.prod.config中有很多重复的代码,则可以使用布尔值isProd仅在某些情况下激活某些功能,并且只有一个webpack.config.js文件。

const isProd = (process.env.NODE_ENV === 'production');

 if (isProd) {
     plugins.push(new AotPlugin({
      "mainPath": "main.ts",
      "hostReplacementPaths": {
        "environments/index.ts": "environments/index.prod.ts"
      },
      "exclude": [],
      "tsConfigPath": "src/tsconfig.app.json"
    }));
    plugins.push(new UglifyJsPlugin({
      "mangle": {
        "screw_ie8": true
      },
      "compress": {
        "screw_ie8": true,
        "warnings": false
      },
      "sourceMap": false
    }));
  }

顺便说一句:DedupePlugin插件已从Webpack中删除。您应该将其从配置中删除。

更新:

除了我以前的回答:

如果要隐藏要发布的代码,请尝试enclosejs.com。它允许您:

  • 制作没有源代码的应用程序发行版
  • 创建一个自解压档案或安装程序
  • 制作封闭源GUI应用程序
  • 将您的资产放入可执行文件中

您可以使用安装 npm install -g enclose

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.