Webpack วิธีสร้างรหัสการผลิตและวิธีใช้งาน


95

ฉันยังใหม่กับ 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 เพื่อเรียกใช้แอปพลิเคชัน"
Randy

4
อินเทอร์เน็ตดีขึ้นมากก่อน webpack เพียงแค่ดูคำถามนี้และคำตอบ
Randy L

คำตอบ:


66

คุณสามารถเพิ่มปลั๊กอินได้ตามที่ @Vikramaditya แนะนำ จากนั้นเพื่อสร้างการผลิต คุณต้องรันคำสั่ง

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

-pบอก webpack เพื่อสร้างสร้างการผลิต คุณต้องเปลี่ยนบิลด์สคริปต์ในpackage.jsonเพื่อรวมแฟล็กการผลิต


7
โอเคขอบคุณ. ข้อสงสัยต่อไปของฉันคือจะรันโค้ดการผลิตได้อย่างไร? เมื่อฉันรันคำสั่งด้านบนมันจะสร้างไฟล์บางไฟล์ในไดเร็กทอรี dist โอเคคอมไพล์สำเร็จ ตอนนี้จะใช้ไฟล์เหล่านี้อย่างไร? ในโหมดการพัฒนาฉันใช้ 'npm start' และเริ่มต้น
Gilson PJ

หากคุณไปที่src/server/bin/serverไฟล์. จากนั้นคุณสามารถหาวิธีการให้บริการไฟล์และอาจเปลี่ยนแปลงได้ สิ่งที่ฉันคิดว่าจะทำคือการเรียกใช้ webpack เพื่อสร้างไฟล์จากนั้นให้บริการ ดูโค้ดของไฟล์นี้
sandeep

@Vikramaditya คุณช่วยฉันด้วยสถานการณ์ในstackoverflow.com/questions/40993795/msbuild-and-webpack
lohiarahul

@GilsonPJ คุณคิดวิธีใช้ไฟล์ UI เหล่านี้หรือไม่?
Randy

คุณต้องติดตั้ง webpack ก่อนโดยใช้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
โปรดทราบว่าการเพิ่มตัวเลือก -p ที่ด้านบนของปลั๊กอิน uglifyJS ทำให้เกิดปัญหาเนื่องจากพยายามอัปเกรดสองครั้ง การลบตัวเลือก -p cli แก้ไขปัญหาเหล่านี้ให้ฉัน
timelf123

ไม่รู้จัก 'NODE_ENV' เป็นคำสั่งภายในหรือภายนอกโปรแกรมที่ใช้งานได้หรือไฟล์แบตช์
Anton Duzenko

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

ฉันเพิ่งมารู้เกี่ยวกับการบีบอัด - webpack -pluginซึ่ง gzips บันเดิลเอาต์พุตของคุณเพื่อลดขนาด เพิ่มสิ่งนี้เช่นกันในรายการปลั๊กอินที่แสดงด้านบนเพื่อเพิ่มประสิทธิภาพโค้ดการผลิตของคุณ

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

ไม่แนะนำให้บีบอัด gzip แบบไดนามิกฝั่งเซิร์ฟเวอร์สำหรับการแสดงไฟล์ฝั่งไคลเอ็นต์แบบคงที่เนื่องจากการใช้งาน CPU มาก


1
ส่วน 'common.js' ทำอะไรบน commonschuckplugin ปลั๊กอินนั้นง่ายที่สุดสำหรับฉันที่จะเข้าใจ
Echiban

2
CommonsChunkPlugin common.jsสารสกัดจากรหัสทั่วไปชิ้นทั้งหมดของคุณและใส่ไว้ในแฟ้มต่างหาก
Vikramaditya

3
คำตอบนี้ใช้ไม่ได้กับ webpack เวอร์ชัน 4 อีกต่อไป
Dennis

20

เรียนรู้แค่นี้เอง ฉันจะตอบคำถามที่สอง:

  1. จะใช้ไฟล์เหล่านี้ได้อย่างไร? ขณะนี้ฉันใช้ webpack-dev-server เพื่อรันแอปพลิเคชัน

แทนที่จะใช้ webpack-dev-server คุณสามารถเรียกใช้ "express" ได้ ใช้ npm install "express" และสร้าง server.js ใน root dir ของโปรเจ็กต์ดังนี้:

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 ขอบคุณที่ชี้ให้เห็น ฉันใหม่มากในการนี้. ฉันคิดว่าเมื่อสร้างรหัสบีบอัดแล้ววิธีการทำงานควรจะเหมือนกัน
Siyuan Jiang

9

คุณสามารถใช้โมดูลargv npm (ติดตั้งโดยรันnpm install argv --save ) เพื่อรับ params ในไฟล์ webpack.config.js ของคุณและสำหรับการใช้งานจริงคุณใช้-p flag "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

@AjaxLeung: คุณต้องรวมargvไว้ในไฟล์const argv = require('argv');
กำหนดค่า webpack

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สำหรับข้อมูลเพิ่มเติม

คุณสามารถแก้ไขได้โดยการลบ UglifyJsPlugin ออกจาก plugins-array หรือเพิ่ม 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()

และ

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

3

หากคุณมีโค้ดที่ซ้ำกันจำนวนมากใน 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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.