Webpack cách xây dựng mã sản xuất và cách sử dụng nó


95

Tôi còn rất mới với webpack, tôi nhận thấy rằng trong phiên bản sản xuất, chúng tôi có thể giảm kích thước của mã tổng thể. Hiện tại, webpack xây dựng khoảng 8MB tệp và main.js khoảng 5MB. Làm thế nào để giảm kích thước của mã trong sản xuất xây dựng? Tôi đã tìm thấy một tệp cấu hình webpack mẫu từ internet và tôi đã định cấu hình cho ứng dụng của mình và tôi chạy npm run buildvà nó bắt đầu xây dựng và nó tạo ra một số tệp trong ./dist/thư mục.

  1. Vẫn còn những tệp này nặng (giống như phiên bản phát triển)
  2. Làm thế nào để sử dụng các tệp này? Hiện tại tôi đang sử dụng webpack-dev-server để chạy ứng dụng.

tệp 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
Bạn đã tìm thấy câu trả lời cho câu hỏi cuối cùng của mình chưa? "Làm thế nào để sử dụng các tệp này? Hiện tại tôi đang sử dụng webpack-dev-server để chạy ứng dụng."
Randy

4
Internet đã tốt hơn rất nhiều trước khi có webpack, chỉ cần nhìn vào câu hỏi này và câu trả lời.
Randy L

Câu trả lời:


66

Bạn có thể thêm các plugin theo đề xuất của @Vikramaditya. Sau đó, để tạo ra bản dựng sản xuất. Bạn phải chạy lệnh

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

Lệnh này -pyêu cầu webpack tạo một bản dựng sản xuất. Bạn phải thay đổi tập lệnh xây dựng trong package.json để bao gồm cờ sản xuất.


6
được rồi cảm ơn. nghi ngờ tiếp theo của tôi là làm thế nào để chạy mã sản xuất? Khi tôi chạy lệnh trên, nó sẽ tạo ra một số tệp trong thư mục dist. ok nó đã biên dịch thành công. bây giờ làm thế nào để sử dụng các tệp này? trong chế độ phát triển, tôi đã sử dụng 'npm start' và nó đã bắt đầu.
Gilson PJ

Nếu bạn đi đến của bạn src/server/bin/server. Sau đó, bạn có thể tìm ra cách nó đang phục vụ các tệp và có thể thay đổi nó. Những gì tôi nghĩ nó sẽ làm là chạy webpack để xây dựng các tệp và sau đó phân phát chúng. Hãy xem mã của tệp này.
sandeep

@Vikramaditya Bạn có thể giúp tôi với kịch bản trong stackoverflow.com/questions/40993795/msbuild-and-webpack
lohiarahul

@GilsonPJ bạn đã tìm ra cách sử dụng các tệp giao diện người dùng này chưa?
Randy

Bạn cần cài đặt webpack đầu tiên sử dụngnpm install webpack
Peter Rader

43

Sau khi quan sát số lượng người xem cho câu hỏi này, tôi quyết định kết luận câu trả lời từ Vikramaditya và Sandeep.

Để xây dựng mã sản xuất, điều đầu tiên bạn phải tạo là cấu hình sản xuất với các gói tối ưu hóa như,

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

Sau đó, trong tệp package.json, bạn có thể định cấu hình quy trình xây dựng với cấu hình sản xuất này

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

bây giờ bạn phải chạy lệnh sau để bắt đầu xây dựng

npm run build

Theo cấu hình xây dựng sản xuất của tôi, webpack sẽ xây dựng nguồn thành ./distthư mục.

Bây giờ mã giao diện người dùng của bạn sẽ có sẵn trong ./dist/thư mục. Định cấu hình máy chủ của bạn để phân phát các tệp này dưới dạng nội dung tĩnh. Làm xong!


7
Ý bạn là gì trong câu cuối cùng của bạn? Làm thế nào để cung cấp các mã này? Tôi biết node.js tự xây dựng một máy chủ. Nhưng làm thế nào tôi có thể chạy nó sau khi tôi có tệp trong ./dist/thư mục?
newguy

6
Chỉ cần lưu ý rằng, việc thêm tùy chọn -p trên đầu plugin uglifyJS gây ra sự cố vì nó cố gắng làm hỏng hai lần. Loại bỏ tùy chọn cli -p cố định những vấn đề đối với tôi
timelf123

'NODE_ENV' không được nhận dạng là lệnh nội bộ hoặc lệnh bên ngoài, chương trình có thể hoạt động hoặc tệp hàng loạt.
Anton Duzenko

2
Đây phải là câu trả lời được chấp nhận, vì không ai nói cách phục vụ trang web Bây giờ mã giao diện người dùng của bạn sẽ có sẵn trong thư mục ./dist/. Đặt máy chủ của bạn để cung cấp các mã giao diện người dùng này cho yêu cầu. và bạn đã hoàn thành.!
jperelli 21/02/17

2
Tôi vẫn chưa hiểu cách "Đặt máy chủ của bạn cung cấp mã giao diện người dùng này cho yêu cầu. Và bạn đã hoàn tất.". Tôi hiểu những gì chúng tôi muốn làm ở đây nhưng tôi không biết làm thế nào để làm điều đó
Randy

42

Sử dụng các plugin này để tối ưu hóa bản dựng sản xuất của bạn:

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

Gần đây tôi đã biết về gói nén-webpack-plugin giúp nén gói đầu ra của bạn để giảm kích thước của nó. Thêm điều này cũng như trong danh sách plugin được liệt kê ở trên để tối ưu hóa hơn nữa mã sản xuất của bạn.

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

Nén gzip động phía máy chủ không được khuyến nghị để cung cấp các tệp phía máy khách tĩnh vì sử dụng nhiều CPU.


1
phần 'common.js' làm gì trên commonschuckplugin? plugin đó là dễ hiểu và khó nhất đối với tôi.
Echiban

2
CommonsChunkPlugin trích xuất mã chung từ tất cả các phần của bạn và đặt nó vào một tệp riêng biệt common.js.
Vikramaditya

3
Câu trả lời này không còn giá trị cho phiên bản webpack 4
Dennis

20

Chỉ cần tự mình học hỏi điều này. Tôi sẽ trả lời câu hỏi thứ hai:

  1. Làm thế nào để sử dụng các tệp này? Hiện tại tôi đang sử dụng webpack-dev-server để chạy ứng dụng.

Thay vì sử dụng webpack-dev-server, bạn chỉ có thể chạy một "express". sử dụng npm install "express" và tạo một server.js trong thư mục gốc của dự án, giống như sau:

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);

Sau đó, trong package.json, hãy thêm một tập lệnh:

"start": "node server.js"

Cuối cùng, chạy ứng dụng: npm run startđể khởi động máy chủ

Bạn có thể xem ví dụ chi tiết tại: https://alejandronapoles.com/2016/03/12/the-simplest-webpack-and-express-setup/ (mã ví dụ không tương thích với các gói mới nhất, nhưng nó sẽ hoạt động với các chỉnh sửa nhỏ)


2
Nếu bạn bắt đầu tìm hiểu những thứ về nodejs, expressjs, v.v. thì tôi muốn nói với bạn. Câu hỏi này là câu hỏi cấp cao. Nó không chỉ dành cho Cách chạy các tệp này. Đó là cho Làm thế nào để giảm thiểu (nén) mã sản xuất và làm thế nào để chạy mã nén
Arpit

1
@Arpit Cảm ơn bạn đã chỉ ra điều này. Tôi rất mới với điều này. Tôi giả định rằng sau khi mã nén được tạo, phương thức chạy sẽ giống nhau.
Siyuan Jiang

9

Bạn có thể sử dụng mô-đun argv npm (cài đặt nó bằng cách chạy npm install argv --save ) để lấy các tham số trong tệp webpack.config.js của mình và đối với sản xuất, bạn sử dụng cờ -p "build": "webpack -p" , bạn có thể thêm điều kiện vào tệp webpack.config.js như bên dưới

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

Và đó là nó.


1
Thay vào đó, hãy sử dụngprocess.argv.indexOf('-p') != -1
AjaxLeung 23/12/16

@AjaxLeung: bạn phải đưa argvvào tệp cấu hình webpack:const argv = require('argv');
kadam

6

Điều này sẽ giúp bạn.

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

Ngoài câu trả lời của Gilson PJ:

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

với

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

vì nó cố gắng làm sai mã của bạn hai lần. Xem https://webpack.github.io/docs/cli.html#production-shortcut-p để biết thêm thông tin.

Bạn có thể khắc phục sự cố này bằng cách xóa UglifyJsPlugin khỏi plugin-mảng hoặc thêm OccectionOrderPlugin và xóa thẻ "-p" -flag. vì vậy một giải pháp khả thi sẽ là

 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

Nếu bạn có nhiều mã trùng lặp trong webpack.dev.config và webpack.prod.config của mình, bạn có thể sử dụng boolean isProdđể kích hoạt một số tính năng chỉ trong một số trường hợp nhất định và chỉ có một tệp webpack.config.js duy nhất.

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

Nhân tiện: Plugin DedupePlugin đã bị xóa khỏi Webpack. Bạn nên xóa nó khỏi cấu hình của mình.

CẬP NHẬT:

Ngoài câu trả lời trước đây của tôi:

Nếu bạn muốn ẩn mã của mình để phát hành, hãy thử enclosejs.com . Nó cho phép bạn:

  • tạo phiên bản phát hành ứng dụng của bạn mà không cần nguồn
  • tạo một kho lưu trữ hoặc trình cài đặt tự giải nén
  • Tạo ứng dụng GUI nguồn đóng
  • Đặt nội dung của bạn bên trong tệp thực thi

Bạn có thể cài đặt nó với npm install -g enclose

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.