webpack——快速入門【一】

學習webpack

https://github.com/webproblem/learning-article#webpackcss

https://github.com/lengziyu/learn-webpackhtml

先跟着下面這個例子來作一遍,由於版本緣由若是你跟着原文可能會出錯,因此我會在這裏修復原文中的錯誤,本文使用的是4.29.3版本node

https://segmentfault.com/a/1190000006178770?utm_source=tag-newestreact

請結合官方文檔來進行學習webpack

https://www.webpackjs.com/concepts/#%E5%85%A5%E5%8F%A3-entry-git

https://webpack.js.org/configuration/dev-server#devservergithub

什麼是webpack

webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖(dependency graph),其中包含應用程序須要的每一個模塊,而後將全部這些模塊打包成一個或多個 bundleweb

爲何使用webpack

① 模塊化開發(import,require)
② 預處理(Less,Sass,ES6,TypeScript……)
③ 主流框架腳手架支持(Vue,React,Angular)
④ 龐大的社區(資源豐富,下降學習成本)npm

總之一句話,方便快捷便於咱們快速的開發。json

快速開始

根據整理的資料進行實際操做,並修正版本更新形成一些命令引起的錯誤,我用的工具是gitbash,平臺爲windows平臺,安裝都只是安裝到項目文件夾中沒有進行全局安裝

建立空文件夾

$ mkdir webpack

$ cd webpack

$ mkdir {app,public}

$ ll
total 0
drwxr-xr-x 1 Administrator 197121 0 二月 13 13:23 app/
drwxr-xr-x 1 Administrator 197121 0 二月 13 13:23 public/

 

安裝webpack

進入文件根目錄,而後安裝webpack到此項目中,這個用的是淘寶鏡像,這樣能夠加快安裝速度。

npm指向淘寶鏡像

$ cnpm install --save-dev webpack platform unsupported webpack@4.29.3 › watchpack@1.6.0 › chokidar@2.1.1 › fsevents@^1.2.7 Package require os(darwin) not compatible with your platform(win32) [fsevents@^1.2.7] optional install error: Package require os(darwin) not compatible with your platform(win32) √ Installed 1 packages √ Linked 267 latest versions √ Run 0 scripts Recently updated (since 2019-02-06): 6 packages (detail see file C:\Users\Administrator.KING\Desktop\webpack\node_modules\.recently_updates.txt) √ All packages installed (292 packages installed from npm registry, used 5s(network 5s), speed 100.79kB/s, json 268(498kB), tarball 0B)

建立文件

cd到app文件夾下建立greeter.js和main.js

$ cd app

$ vi greeter.js

$ vi main.js

 

greeter.js

Greeter.js中定義一個返回包含問候信息的html元素的函數,並依據CommonJS規範導出這個函數爲一個模塊

module.exports = function() {
  var greet = document.createElement('div'); greet.textContent = "小哥哥,快來啊,快活啊"; return greet; };

 

main.js

main.js文件中咱們寫入下述代碼,用以把Greeter模塊返回的節點插入頁面。

const greeter = require('./Greeter.js');
document.querySelector("#root").appendChild(greeter());

 

cd到public下面建立index.html

$ cd ..

$ cd public/
$ vi index.html

index.html

其中bundle.js爲打包後的js文件名稱

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Webpack Sample Project</title>
  </head>
  <body>
    <div id='root'>
    </div>
    <script src="bundle.js"></script>
  </body>
</html>

 

打包

這裏安裝使用的就是非全局安裝,因此打包也使用非全局打包

$ node_modules/.bin/webpack app/main.js -o public/bundle.js
Hash: c6d5fc7966695da6f6cd
Version: webpack 4.29.3
Time: 358ms
Built at: 2019-02-13 12:54:49
Asset Size Chunks Chunk Names
bundle.js 1.09 KiB 0 [emitted] main
Entrypoint main = bundle.js
[0] ./app/main.js 255 bytes {0} [built]
[1] ./app/Greeter.js 304 bytes {0} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

進入public打開index.html便可查看效果

 

建立配置文件

在根目錄下建立webpack.config.js文件,主要配置入口文件和打包後文件

module.exports = {
  entry:  __dirname + "/app/main.js",//已屢次說起的惟一入口文件
  output: {
    path: __dirname + "/public",//打包後的文件存放的地方
    filename: "bundle.js"//打包後輸出文件的文件名
  }
}

 

:「__dirname」是node.js中的一個全局變量,它指向當前執行腳本所在的目錄。

 

修改greeter.js

就是改了下文字內容~

module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = "We still hava a long way to go.";
  return greet;
};

從新打包

這時候就很簡單了,固然若是全局安裝的話,直接webpack就能夠了

$ node_modules/.bin/webpack
Hash: 9725aade1d1273904ee2
Version: webpack 4.29.3
Time: 364ms
Built at: 2019-02-13 14:19:38
    Asset     Size  Chunks             Chunk Names
bundle.js  1.1 KiB       0  [emitted]  main
Entrypoint main = bundle.js
[0] ./app/main.js 255 bytes {0} [built]
[1] ./app/Greeter.js 314 bytes {0} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

 

自定義打包命令

npm進行配置後能夠在命令行中使用簡單的npm start命令來替代上面略微繁瑣的命令。在package.json中對scripts對象進行相關設置

若是沒有這個package.json文件不要慌,直接npm init初始化一個就能夠了,如今開始配置。

反正是測試不發佈的,因此能夠直接回車便可。

$ npm init

打開package.json修改scripts對象添加如下內容

我這裏是非全局安裝全部添加的是node_modules/.bin/webpack,全局安裝的直接添加webpack便可

"start":"node_modules/.bin/webpack"  

完整的json文件以下

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "dependencies": {
    "webpack-cli": "^3.2.3",
    "webpack": "^4.29.3"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start":"node_modules/.bin/webpack"  
  },
  "author": "",
  "license": "ISC"
}

再次修改greeter.js

module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = "Hello world";
  return greet;
};

使用自定義的命令打包

$ npm start

> webpack@1.0.0 start D:\wamp\www\webpack
> webpack

Hash: 1b28a19fd8d2277de6f0
Version: webpack 4.29.3
Time: 376ms
Built at: 2019-02-13 14:31:57
    Asset      Size  Chunks             Chunk Names
bundle.js  1.08 KiB       0  [emitted]  main
Entrypoint main = bundle.js
[0] ./app/main.js 255 bytes {0} [built]
[1] ./app/Greeter.js 294 bytes {0} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

其中有個關於npm的小知識,須要各位到原文去查看,畢竟咱們也是從人家那邊學習,不給讚揚給給訪問也能夠啊

 

生成Source Maps

webpack的配置文件中配置source maps,須要配置devtool,它有如下四種不一樣的配置選項,各具優缺點,描述以下:

devtool選項 配置結果
source-map 在一個單獨的文件中產生一個完整且功能徹底的文件。這個文件具備最好的source map,可是它會減慢打包速度;
cheap-module-source-map 在一個單獨的文件中生成一個不帶列映射的map,不帶列映射提升了打包速度,可是也使得瀏覽器開發者工具只能對應到具體的行,不能對應到具體的列(符號),會對調試形成不便;
eval-source-map 使用eval打包源文件模塊,在同一個文件中生成乾淨的完整的source map。這個選項能夠在不影響構建速度的前提下生成完整的sourcemap,可是對打包後輸出的JS文件的執行具備性能和安全的隱患。在開發階段這是一個很是好的選項,在生產階段則必定不要啓用這個選項;
cheap-module-eval-source-map 這是在打包文件時最快的生成source map的方法,生成的Source Map 會和打包後的JavaScript文件同行顯示,沒有列映射,和eval-source-map選項具備類似的缺點;

上述選項由上到下打包速度愈來愈快,不過同時也具備愈來愈多的負面做用,較快的打包速度的後果就是對打包後的文件的的執行有必定影響。

對小到中型的項目中,eval-source-map是一個很好的選項,再次強調你只應該開發階段使用它,咱們繼續對上文新建的webpack.config.js,進行以下配置:

module.exports = {
    devtool: 'eval-source-map',
    entry: __dirname + "/app/main.js",
    output: {
        path: __dirname + "/public",
        filename: "bundle.js"
    }
}

可能有的同窗一直看到了這個警告

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

這是什麼呢,由於咱們沒有在webpack.config.js中配置模式形成了,咱們順手也配置下吧

development 開發環境
production  生產環境
module.exports = {
    mode:'development',
    devtool: 'eval-source-map',
    entry: __dirname + "/app/main.js",
    output: {
        path: __dirname + "/public",
        filename: "bundle.js"
    }
}

 

構建本地服務器

可讓瀏覽器監聽你的代碼的修改,並自動刷新顯示修改後的結果

$ cnpm install --save-dev webpack-dev-server
platform unsupported webpack-dev-server@3.1.14 › chokidar@2.1.1 › fsevents@^1.2.7 Package require os(darwin) not compatible with your platform(win32)
[fsevents@^1.2.7] optional install error: Package require os(darwin) not compatible with your platform(win32)
√ Installed 1 packages
√ Linked 429 latest versions
√ Run 0 scripts
Recently updated (since 2019-02-06): 7 packages (detail see file D:\wamp\www\webpack\node_modules\.recently_updates.txt)
√ All packages installed (472 packages installed from npm registry, used 19s(network 19s), speed 43.94kB/s, json 430(799.49kB), tarball 36.44kB)

修改配置文件webpack.config.js

module.exports = {
    mode:'development',
    devtool: 'eval-source-map',
    entry: __dirname + "/app/main.js",
    output: {
        path: __dirname + "/public",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./public",//本地服務器所加載的頁面所在的目錄
        historyApiFallback: true,//不跳轉
        inline: true//實時刷新
  }
}

package.json中的scripts對象中添加以下命令,用以開啓本地服務器:

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "dependencies": {
    "webpack-cli": "^3.2.3",
    "webpack": "^4.29.3"
  },
  "devDependencies": {
    "webpack-dev-server": "^3.1.14"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node_modules/.bin/webpack",
    "server": "webpack-dev-server --open"
  },
  "author": "",
  "license": "ISC"
}

運行服務

$ npm run server

> webpack@1.0.0 server D:\wamp\www\webpack
> webpack-dev-server --open

i 「wds」: Project is running at http://localhost:8081/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from ./public
i 「wds」: 404s will fallback to /index.html
i 「wdm」: wait until bundle finished: /
i 「wdm」: Hash: a3f5179d4ce1ace1f048
Version: webpack 4.29.3
Time: 744ms
Built at: 2019-02-13 14:56:40
    Asset     Size  Chunks             Chunk Names
bundle.js  867 KiB    main  [emitted]  main
Entrypoint main = bundle.js
[0] multi ./node_modules/_webpack-dev-server@3.1.14@webpack-dev-server/client?http://localhost:8081 ./app/main.js 40 bytes {main} [built]
[./app/Greeter.js] 294 bytes {main} [built]
[./app/main.js] 255 bytes {main} [built]
[./node_modules/_ansi-html@0.0.7@ansi-html/index.js] 4.16 KiB {main} [built]
[./node_modules/_ansi-regex@2.1.1@ansi-regex/index.js] 135 bytes {main} [built]
[./node_modules/_html-entities@1.2.1@html-entities/index.js] 231 bytes {main} [built]
[./node_modules/_loglevel@1.6.1@loglevel/lib/loglevel.js] 7.68 KiB {main} [built]
[./node_modules/_sockjs-client@1.3.0@sockjs-client/dist/sockjs.js] 180 KiB {main} [built]
[./node_modules/_strip-ansi@3.0.1@strip-ansi/index.js] 161 bytes {main} [built]
[./node_modules/_webpack-dev-server@3.1.14@webpack-dev-server/client/index.js?http://localhost:8081] ./node_modules/_webpack-dev-server@3.1.14@webpack-dev-server/client?http://localhost:8081 7.78 KiB {main} [built]
[./node_modules/_webpack-dev-server@3.1.14@webpack-dev-server/client/overlay.js] 3.58 KiB {main} [built]
[./node_modules/_webpack-dev-server@3.1.14@webpack-dev-server/client/socket.js] 1.05 KiB {main} [built]
[./node_modules/url/url.js] 22.8 KiB {main} [built]
[./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 75 bytes {main} [built]
    + 12 hidden modules
i 「wdm」: Compiled successfully.

 

 

Loader

配置loader以前,咱們把Greeter.js裏的問候消息放在一個單獨的JSON文件裏,並經過合適的配置使Greeter.js能夠讀取該JSON文件的值,各文件修改後的代碼以下:

在app文件夾下新增一個greet.json文件

greet.json

{
  "greetText": "Hi there and greetings from JSON!"
}

 

greeter.js

var config = require('./greet.json');
module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = config.greetText;;
  return greet;
};

自動編譯的結果顯示

 

Babel

Babel實際上是一個編譯JavaScript的平臺,它能夠編譯代碼幫你達到如下目的:

  • 讓你能使用最新的JavaScript代碼(ES6,ES7...),而不用管新標準是否被當前使用的瀏覽器徹底支持;
  • 讓你能使用基於JavaScript進行了拓展的語言,好比React的JSX;

安裝依賴包

新版本的要求依賴包必須是7的,否則是會報錯的,報錯不可怕,只要看信息總會解決的!

$ cnpm install --save-dev babel-core babel-loader@7  babel-preset-env babel-preset-react

√ Installed 4 packages
√ Linked 121 latest versions
√ Run 0 scripts
peerDependencies WARNING babel-loader@* requires a peer of @babel/core@^7.0.0 but none was installed
Recently updated (since 2019-02-06): 3 packages (detail see file D:\wamp\www\webpack\node_modules\.recently_updates.txt)
√ All packages installed (113 packages installed from npm registry, used 4s(network 4s), speed 329.85kB/s, json 125(427.86kB), tarball 873.08kB)

配置webpack.config.js文件

module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    entry: __dirname + "/app/main.js",
    output: {
        path: __dirname + "/public",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./public",
        historyApiFallback: true,
        inline: true
    },
    module: {
        rules: [{
            test: /(\.jsx|\.js)$/,
            use: {
                loader: "babel-loader",
                options: {
                    presets: [
                        "env", "react"
                    ]
                }
            },
            exclude: /node_modules/
        }]
    }
}

如今你的webpack的配置已經容許你使用ES6以及JSX的語法了。繼續用上面的例子進行測試,不過此次咱們會使用React,記得先安裝 React 和 React-DOM

我只想學下webpack你還給我贈送了react......

$ cnpm install --save react react-dom
√ Installed 2 packages
√ Linked 5 latest versions
√ Run 0 scripts
Recently updated (since 2019-02-06): 5 packages (detail see file D:\wamp\www\webpack\node_modules\.recently_updates.txt)
√ All packages installed (5 packages installed from npm registry, used 1s(network 1s), speed 901.37kB/s, json 7(32.33kB), tarball 1.21MB)

接下來咱們使用ES6的語法,更新greeter.js並返回一個React組件

import React, {Component} from 'react'
import config from './config.json';

class Greeter extends Component{
  render() {
    return (
      <div>
        {config.greetText}
      </div>
    );
  }
}

export default Greeter

修改main.js以下,使用ES6的模塊定義和渲染Greeter模塊

import React from 'react';
import {render} from 'react-dom';
import Greeter from './greeter';

render(<Greeter />, document.getElementById('root'));

而後從新打包

$ npm start

> webpack@1.0.0 start D:\wamp\www\webpack
> webpack

Hash: bcd934684f9507b2fc78
Version: webpack 4.29.3
Time: 2240ms
Built at: 2019-02-13 16:13:51
    Asset      Size  Chunks             Chunk Names
bundle.js  2.16 MiB    main  [emitted]  main
Entrypoint main = bundle.js
[./app/Greeter.js] 5.28 KiB {main} [built]
[./app/greet.json] 58 bytes {main} [built]
[./app/main.js] 1.23 KiB {main} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
    + 11 hidden modules

分開配置

 雖然能夠在webpack.config.js中配置,可是babel的配置項仍是不少的,因此咱們單獨命名一個.babelrc的配置文件

webpack會自動調用.babelrc的配置文件

webpack.config.js

module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    entry: __dirname + "/app/main.js",
    output: {
        path: __dirname + "/public",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./public",
        historyApiFallback: true,
        inline: true
    },
    module: {
        rules: [{
            test: /(\.jsx|\.js)$/,
            use: {
                loader: "babel-loader",
            },
            exclude: /node_modules/
        }]
    }
}

.babelrc

{
  "presets": ["react", "env"]
}

 

plugins

插件(Plugins)是用來拓展Webpack功能的,它們會在整個構建過程當中生效,執行相關的任務。
Loaders和Plugins經常被弄混,可是他們實際上是徹底不一樣的東西,能夠這麼來講,loaders是在打包構建過程當中用來處理源文件的(JSX,Scss,Less..),一次處理一個,插件並不直接操做單個文件,它直接對整個構建過程其做用。

Webpack有不少內置插件,同時也有不少第三方插件,可讓咱們完成更加豐富的功能。

如今咱們就用內置插件作個小東西
 
修改webpack.config.js配置文件
const webpack = require('webpack'); //引入內置插件
module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    entry: __dirname + "/app/main.js",
    output: {
        path: __dirname + "/public",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./public",
        historyApiFallback: true,
        inline: true
    },
    module: {
        rules: [{
                    test: /(\.jsx|\.js)$/,
                    use: {
                        loader: "babel-loader",
                    },
                    exclude: /node_modules/
                }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版權全部,翻版必究')
    ],
}

從新打包

$ npm start

> webpack-project@1.0.0 start D:\wamp\www\webpack
> webpack

Hash: 1f027912d9db7df7db0e
Version: webpack 4.29.3
Time: 1397ms
Built at: 2019-02-14 10:20:36
    Asset      Size  Chunks             Chunk Names
bundle.js  2.16 MiB    main  [emitted]  main
Entrypoint main = bundle.js
[./app/greet.json] 58 bytes {main} [built]
[./app/greeter.js] 5.39 KiB {main} [built]
[./app/main.js] 1.23 KiB {main} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
    + 11 hidden modules

 查看bundle.js文件

 

HtmlWebpackPlugin

這個插件的做用是依據一個簡單的index.html模板,生成一個自動引用你打包後的JS文件的新index.html。這在每次生成的js文件名稱不一樣時很是有用(好比添加了hash值)。
 
安裝
$ cnpm install --save-dev html-webpack-plugin
√ Installed 1 packages
√ Linked 55 latest versions
√ Run 0 scripts
Recently updated (since 2019-02-07): 1 packages (detail see file D:\wamp\www\webpack\node_modules\.recently_updates.txt)
√ All packages installed (54 packages installed from npm registry, used 4s(network 4s), speed 38.09kB/s, json 56(166.11kB), tarball 0B)

1.移除public文件夾,在根目錄下建立build文件夾,利用此插件,index.html文件會自動生成,此外CSS已經經過前面的操做打包到JS中了。

2.在app目錄下,建立一個index.tmpl.html文件模板,這個模板包含title等必須元素,在編譯過程當中,插件會依據此模板生成最終的html頁面,會自動添加所依賴的 css, js,favicon等文件,index.tmpl.html中的模板源代碼以下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Webpack Sample Project</title>
  </head>
  <body>
    <div id='root'>
    </div>
  </body>
</html>

 

更新webpack.config.js配置文件

const webpack = require('webpack'); //引入內置插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    entry: __dirname + "/app/main.js",
    output: {
        path: __dirname + "/build",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./build",//本地服務器所加載的頁面所在的目錄
        historyApiFallback: true,//不跳轉
        inline: true//實時刷新
    },
    module: {
        rules: [{
                    test: /(\.jsx|\.js)$/,
                    use: {
                        loader: "babel-loader",
                    },
                    exclude: /node_modules/
                }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版權全部,翻版必究'),
        new HtmlWebpackPlugin({
            template: __dirname + "/app/index.tmpl.html"//new 一個這個插件的實例,並傳入相關的參數
        })
    ],
}

從新打包,從新編譯

$ npm start

> webpack-project@1.0.0 start D:\wamp\www\webpack
> webpack

Hash: b3fdcd46964738ddb0a3
Version: webpack 4.29.3
Time: 2052ms
Built at: 2019-02-14 10:37:47
     Asset       Size  Chunks             Chunk Names
 bundle.js   2.16 MiB    main  [emitted]  main
index.html  417 bytes          [emitted]
Entrypoint main = bundle.js
[./app/greet.json] 58 bytes {main} [built]
[./app/greeter.js] 5.39 KiB {main} [built]
[./app/main.js] 1.23 KiB {main} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
    + 11 hidden modules
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [./node_modules/_html-webpack-plugin@3.2.0@html-webpack-plugin/lib/loader.js!./app/index.tmpl.html] 615 bytes {0} [built]
    [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {0} [built]
    [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]
        + 1 hidden module
$ npm run server

build文件夾中多出兩個文件,頁面顯示正常

 

產品階段的構建

目前爲止,咱們已經使用webpack構建了一個完整的開發環境。可是在產品階段,可能還須要對打包的文件進行額外的處理,好比說優化,壓縮,緩存以及分離CSS和JS。

對於複雜的項目來講,須要複雜的配置,這時候分解配置文件爲多個小的文件可使得事情層次分明,以上面的例子來講,咱們建立一個webpack.production.config.js的文件,在裏面加上基本的配置,它和原始的webpack.config.js很像,以下

onst webpack = require('webpack'); //引入內置插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode: 'production', //模式修改了
    devtool: 'null',//修改成null壓縮打包代碼
    entry: __dirname + "/app/main.js",
    output: {
        path: __dirname + "/build",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./build",//本地服務器所加載的頁面所在的目錄
        historyApiFallback: true,//不跳轉
        inline: true//實時刷新
    },
    module: {
        rules: [{
                    test: /(\.jsx|\.js)$/,
                    use: {
                        loader: "babel-loader",
                    },
                    exclude: /node_modules/
                }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版權全部,翻版必究'),
        new HtmlWebpackPlugin({
            template: __dirname + "/app/index.tmpl.html"//new 一個這個插件的實例,並傳入相關的參數
        })
    ],
}

 

package.json

 

{
  "name": "webpack-project",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "dependencies": {
    "react": "^16.8.1",
    "react-dom": "^16.8.1",
    "webpack": "^4.29.3",
    "webpack-cli": "^3.2.3"
  },
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "html-webpack-plugin": "^3.2.0",
    "webpack-dev-server": "^3.1.14"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node_modules/.bin/webpack",
    "server": "webpack-dev-server --open",
    "build": "set NODE_ENV=production && webpack --config ./webpack.production.config.js --progress" //windows
  },
  "author": "",
  "license": "ISC"
}

優化插件

webpack提供了一些在發佈階段很是有用的優化插件,它們大多來自於webpack社區,能夠經過npm安裝,經過如下插件能夠完成產品發佈階段所需的功能

  • OccurenceOrderPlugin :爲組件分配ID,經過這個插件webpack能夠分析和優先考慮使用最多的模塊,併爲它們分配最小的ID
  • UglifyJsPlugin:壓縮JS代碼; //此插件已經不能使用
  • ExtractTextPlugin:分離CSS和JS文件  //extract-text-webpack-plugin目前版本不支持webpack4

咱們繼續用例子來看看如何添加它們,OccurenceOrder 和 UglifyJS plugins 都是內置插件,你須要作的只是安裝其它非內置插件

 安裝

$ cnpm install extract-text-webpack-plugin@next
√ Installed 1 packages
√ Linked 12 latest versions
√ Run 0 scripts
Recently updated (since 2019-02-07): 2 packages (detail see file D:\wamp\www\webpack\node_modules\.recently_updates.txt)
√ All packages installed (5 packages installed from npm registry, used 2s(network 2s), speed 62.08kB/s, json 13(97.33kB), tarball 12.91kB)

修改webpack.production.config.js

/*
* @Author: wyy
* @Date:   2019-02-14 10:45:50
* @Email:  2752154874@qq.com
* @Last Modified by:   wyy
* @Last Modified time: 2019-02-14 10:49:01
*/
const webpack = require('webpack'); //引入內置插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
    mode: 'production',
    devtool: 'null',//修改成null壓縮打包代碼
    entry: __dirname + "/app/main.js",
    output: {
        path: __dirname + "/build",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./build",//本地服務器所加載的頁面所在的目錄
        historyApiFallback: true,//不跳轉
        inline: true//實時刷新
    },
    module: {
        rules: [{
                    test: /(\.jsx|\.js)$/,
                    use: {
                        loader: "babel-loader",
                    },
                    exclude: /node_modules/
                }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版權全部,翻版必究'),
        new HtmlWebpackPlugin({
            template: __dirname + "/app/index.tmpl.html"//new 一個這個插件的實例,並傳入相關的參數
        }),
        new webpack.optimize.OccurrenceOrderPlugin(),
        new ExtractTextPlugin("style.css")
    ],
}

 進行編譯

$ npm run build

> webpack-project@1.0.0 build D:\wamp\www\webpack
> set NODE_ENV=production && webpack --config ./webpack.production.config.js --progress

Hash: c9e8a924b38580a073b8
Version: webpack 4.29.3
Time: 3371ms
Built at: 2019-02-14 11:26:04
     Asset       Size  Chunks             Chunk Names
 bundle.js    117 KiB       0  [emitted]  main
index.html  417 bytes          [emitted]
Entrypoint main = bundle.js
 [2] ./app/main.js 1.23 KiB {0} [built]
 [8] (webpack)/buildin/global.js 472 bytes {0} [built]
 [9] ./app/greeter.js 5.39 KiB {0} [built]
[10] ./app/greet.json 58 bytes {0} [built]
    + 7 hidden modules
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [0] ./node_modules/_html-webpack-plugin@3.2.0@html-webpack-plugin/lib/loader.js!./app/index.tmpl.html 615 bytes {0} [built]
    [2] (webpack)/buildin/global.js 472 bytes {0} [built]
    [3] (webpack)/buildin/module.js 497 bytes {0} [built]
        + 1 hidden module

 

 

最後附上本文的demo

https://github.com/wangyang0210/bky/tree/webpack

相關文章
相關標籤/搜索