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

时间:2016-01-28 06:14:36

标签: node.js reactjs npm webpack webpack-dev-server

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

  1. 这些文件仍然很重(与开发版本相同)
  2. 如何使用这些文件?目前我正在使用webpack-dev-server 运行应用程序。
  3. 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]
      }
    };
    

9 个答案:

答案 0 :(得分:55)

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

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

-p告诉webpack生成生成版本。您必须更改 package.json 中的构建脚本以包含生产标记。

答案 1 :(得分:39)

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

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

我最近了解了 compression-webpack-plugin   gzips您的输出束以减小其大小。   在上面列出的插件列表中添加它以进一步优化您的生产代码。

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

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

答案 2 :(得分:33)

在观察了这个问题的观众人数之后,我决定结束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/目录中提供。配置服务器以将这些文件作为静态资产提供。完成!

答案 3 :(得分:12)

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

  1. 如何使用这些文件?目前我正在使用webpack-dev-server来运行该应用程序。
  2. 您可以只运行" 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);
    

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

    "start": "node server.js"
    

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

    详细示例见: https://alejandronapoles.com/2016/03/12/the-simplest-webpack-and-express-setup/ (示例代码与最新的软件包不兼容,但它可以使用小的调整)

答案 4 :(得分:8)

您可以使用argv npm模块(通过运行 npm install argv --save 来安装它)以获取webpack.config.js文件中的params以及您使用的生产< strong> -p 标记&#34; build&#34;:&#34; webpack -p&#34; ,您可以在webpack.config.js文件中添加条件,如下所示< / p>

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

就是这样。

答案 5 :(得分: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
    })
  ],

答案 6 :(得分:4)

除了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"
},

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

您可以通过从plugins-array中删除UglifyJsPlugin来修复此问题,或者添加OccurrenceOrderPlugin并删除&#34; -p&#34; -flag。所以一个可能的解决方案是

 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"
},

答案 7 :(得分: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

进行安装

答案 8 :(得分:0)

包括 Webpack 5 在内的最新答案

对于 Webpack(版本不记得了)

NODE_ENV=production webpack --config ./webpack.production.config.js

对于 Webpack <4

plugins: [
    new webpack.DefinePlugin({
        'process.env':{
            'NODE_ENV': JSON.stringify('production')
                        //for development -> JSON.stringify('development')
        }
    })
]

对于 webpack >=4(包括 webpack 5) - 指定 mode

 module.exports = {
   mode: 'production', //for development -> development
   devtool: 'inline-source-map',
   ...
 };

引自 Webpack 官方 website

<块引用>

从 webpack v4 开始,指定模式会自动配置 为您定义插件