webpack系統配置

簡言之,webpack 是一個模塊打包器 (module bundler),可以將任何資源如 JavaScript 文件、CSS 文件、圖片等打包成一個或少數文件。javascript

爲何要用Webpack?css

首先,定義已經說明了 webpack 能將多個資源模塊打包成一個或少數文件,這意味着與以往的發起多個 HTTP 請求來得到資源相比,如今只須要發起少許的 HTTP 請求。html

其次,webpack 能將你的資源轉換爲最適合瀏覽器的「格式」,提高應用性能。好比只引用被應用使用的資源 (剔除未被使用的代碼),懶加載資源 (只在須要的時候才加載相應的資源)。再次,對於開發階段,webpack 也提供了實時加載和熱加載的功能,大大地節省了開發時間。除此以外,還有許多優秀之處之處值得去挖掘。不過,webpack 最核心的仍是打包的功能。前端

webpack,gulp/grunt,npm,它們有什麼區別?html5

webpack 是模塊打包器(module bundler),把全部的模塊打包成一個或少許文件,使你只需加載少許文件便可運行整個應用,而無需像以前那樣加載大量的圖片,css文件,js文件,字體文件等等。而gulp/grunt 是自動化構建工具,或者叫任務運行器(task runner),是把你全部重複的手動操做讓代碼來作,例如壓縮JS代碼、CSS代碼,代碼檢查、代碼編譯等等,自動化構建工具並不能把全部模塊打包到一塊兒,也不能構建不一樣模塊之間的依賴圖。二者來比較的話,gulp/grunt 沒法作模塊打包的事,webpack 雖然有 loader 和 plugin能夠作一部分 gulp/grunt 能作的事,可是終究 webpack 的插件仍是不如 gulp/grunt 的插件豐富,能作的事比較有限。因而有人二者結合着用,將 webpack 放到 gulp/grunt 中用。然而,更好的方法是用 npm scripts 取代 gulp/grunt,npm 是 node 的包管理器 (node package manager),用於管理 node 的第三方軟件包,npm 對於任務命令的良好支持讓你最終省卻了編寫任務代碼的必要,取而代之的,是老祖宗的幾個命令行,僅靠幾句命令行就足以完成你的模塊打包和自動化構建的全部需求。java

首先看下webpack最基本的應用:node

全局使用react

一、全局安裝webpack:jquery

cnpm install webpack -g

二、建立項目:webpack

mkdir app

在 app 目錄下添加 runoob1.js 文件,代碼以下:

document.write("It works.");

在 app 目錄下添加 index.html 文件,代碼以下:

<html>
    <head> <meta charset="utf-8"> </head> <body> <script type="text/javascript" src="bundle.js" charset="utf-8"></script> </body> </html>

接下來咱們使用 webpack 命令來打包:

webpack runoob1.js bundle.js

執行以上命令會編譯 runoob1.js 文件並生成bundle.js 文件,成功後輸出信息以下所示:

Hash: a41c6217554e666594cb
Version: webpack 1.12.13
Time: 50ms
    Asset     Size  Chunks             Chunk Names
bundle.js  1.42 kB       0  [emitted]  main
   [0] ./runoob1.js 29 bytes {0} [built]

在瀏覽器中打開 index.html,輸出結果以下:

webpack的使用,最複雜的一部分是莫過於它的配置項。webpack經過你的配置項,放置全部與打包相關的信息。一個基本的配置包括:

module.exports = { entry: '', output: {}, module: { rules: [] }, plugins: [], };

你若是要打包一個文件,那首先要指定文件的地址,也就是entry;打包以後放在那裏呢,也就是output;打包過程當中文件要通過怎麼樣的處理,也就是rules中的loader;如何可以使webpack打包更快,體積更小呢,也就是plugins。這些配置相輔相成,緊密結合。

安裝到本項目:

npm i -D // npm install --save-dev的簡寫,是指安裝模塊並保存到package.json的devDependencies
npm i webpack -D //安裝最新的穩定版本
npm i webpack@<version> -D // 安裝指定版本
npm i webpack@beta -D // 安裝最新的體驗版本

安裝完成後能夠經過如下途徑運行安裝到本項目的webpack:

一、根項目目錄下對應的命令行裏經過".\node_modules\.bin\webpack"(注意:不是"./node_modules/.bin/webpack")運行webpack的可執行文件。 

二、在npm script裏定義的任務會優先使用本項目下的webpack,代碼以下:

"scripts": { "start": "webpack --config webpack.config.js" }

雖然介紹了以上兩種安裝方式, 可是咱們推薦安裝到本項目,緣由是可防止不一樣的項目因依賴不一樣版本的webpack而致使衝突。

模塊化:

一、Common.js:

// 導出 function moduleA(){ ... } module.exports = moduleA; // 導入 const moduleA = require("./moduleA "); 

CommonJS的優勢在於:

a、代碼可複用於Node.js環境下並運行,例如作同構應用;

b、經過NPM發佈的不少第三方模塊都採用了CommonJS規範。

CommonJS的缺點:

這樣的代碼沒法直接運行在瀏覽器環境下,必須經過工做轉換成標準的ES5。

二、AMD:

與CommonJS最大的不一樣是採用了異步的方式去加載依賴的模塊。

採用AMD導入導出的代碼以下:

// 定義一個模塊: define("module", ["dep"], function(dep){ return exports; }); // 導入 require("module", function(module){ })

AMD的優勢:

a、可在不轉換代碼的狀況下直接在瀏覽器中運行;

b、可異步加載依賴;

c、可並行加載多個依賴;

d、代碼可運行在瀏覽器環境和Node.js環境下。

缺點:

JavaScript運行環境沒有原生支持AMD,須要先導入實現了AMD的庫後才能正常使用。

三、es6模塊化:

ES6 模塊化是國際標準化組織 ECMA 提出的 JavaScript 模塊化規範,它在語言層面上實現了模塊化。瀏覽器廠商和 Node.js都宣佈要原生支持該規範 。 它將逐漸取代 CommonJS 和AMD 規範,成爲瀏覽器和服務器通用的模塊解決方案 。

採用 ES6 模塊化導入及導出的代碼以下:

//導入
import { readFile } from ’ fs ’; import React from ’ react ’ ; //導出 export function hello {) { }; export default { // ... }; 

ES6 模塊雖然是終極模塊化方案,但它的缺點在於目前沒法直接運行在大部分 JavaScript運行環境下,必須經過工具轉換成標準的 ES5 後才能正常運行。 

4. 樣式文件申的模塊化:

除了 JavaScript 開始進行模塊化改造,前端開發裏的樣式文件也支持模塊化。以 scss 爲例,將一些經常使用的樣式片斷放進一個通用的文件裏,再在另 一個文件裏經過@ import 語句導入和使用這些樣式片斷 :
// util.scss 文件

// util.scss 文件

// 定義樣式片斷
@mixin center {
    //水平堅直居中
    position: absolute;
    left: 50%;
    top : 50%;
    transform : translate(-50%,-50%);
}

// main.scss 文件

// 導入和使用 util.scss 中定義的樣式片斷
@import "util";
#box{
    @include center ;
}

webpack版本不一樣,使用方式可能也會不一樣,下面來看下webpack3的使用:

1、webpack3的使用:

普通打包:

一、首先,建立一個目錄,好比test11,使用npm初始化目錄:

npm init

執行後會有一系列選項,能夠按回車鍵快速確認,完成後會在test11目錄生成一個package.json的文件。

二、以後在本機局部安裝webpack:

npm install webpack@3.10.0 --save-dev

--save-dev會作爲開發依賴來安裝webpack。安裝成功後,在package.json中會多了一項配置:

"devDependencies" : { "webpack": "^3.10.0", }

此時的package.json文件爲:

{
  "name": "test11", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^3.10.0" } } 

看到"devDependencies"中含有webpack,就說明已經安裝成功了,很快就能夠啓動一個webpack工程。

接下來新建一個src目錄而且在src目錄下新建main.js文件:

console.log("hello webpack");

新建一個index.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./dist/bundle.js"></script>
</head>
<body>

</body>
</html>

如今的文件夾目錄結構以下:

執行如下命令打包main.js:

webpack src/main.js dist/bundle.js

若是有webpack.config.js文件,則直接輸入「webpack」命令便可打包:

webpack

其中webpack.config.js配置以下:

var webpack = require('webpack'); var path = require('path'); // 引入node的path模塊 module.exports={ entry: { entry: './src/main.js' // 入口文件 }, output: { path: path.resolve(__dirname, 'dist'), // 打包路勁(獲取絕對路徑) filename: 'bundle.js' // 打包文件 }, module: {}, plugins: [], devServer: {}, }

出現以下信息說明打包成功:

經過npm run build命令打包:

修改package.json中的script命令:

"build": "webpack src/main.js dist/bundle.js"
{
  "name": "test11", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack src/main.js dist/bundle.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.1.4", "webpack": "^3.10.0" } }

 而後命令行輸入:

npm run build

一樣也能夠打包。

 實現自動監聽:

修改package.json文件中的script命令:

"watch": "npm run build -- --watch"
{
  "name": "test11", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack src/main.js dist/bundle.js", "watch": "npm run build -- --watch" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.1.4", "webpack": "^3.10.0" } } 

命令行輸入:npm run watch  打包。

 2、webpack4的使用:

一、首先,建立一個目錄,好比demo,使用npm初始化目錄:

npm init

執行後會有一系列選項,能夠按回車鍵快速確認,完成後會在demo目錄生成一個package.json的文件。

二、以後在本機局部安裝webpack:

npm install webpack --save-dev

--save-dev會作爲開發依賴來安裝webpack。安裝成功後,在package.json中會多了一項配置:

"devDependencies" : {

 "webpack": "^4.16.3",

}

此外還需安裝webpack-cli:

npm install webpack-cli --save-dev

三、配置webpack:

建立 webpack.config.js 文件做爲webpack的配置文件。

var path = require('path');

var config = {
    entry: {
        main: './main'//配置的單入口,webpack會從main.js開始工做
    },
    output: {
        path: path.join(__dirname, './dist'),//存放打包後文件的輸出目錄
        publicPath: '/dist/',//指定資源文件的引用目錄,
        filename: 'bundle.js'//指定輸出文件的名稱,只要在html中引用它便可

    }
};

module.exports = config;

新建index.html文件:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> </head> <body> <div id='root'></div> <script type="text/javascript" src="./dist/bundle.js" charset="utf-8"></script> </body> </html>

新建main.js文件:

document.write("test webpack4.0");

如今工程目錄結構爲:

四、使用webpack:

設置開發或者生產模式:

在 webpack.config.js 裏設置

mode: 'development'

爲了方便使用,咱們在package.json里加入webpack打包的命令方便咱們使用修改script項 :

"scripts": { "build": "npx webpack --config webpack.config.js" },

這樣再次運行咱們直接輸入:

npm run build

就能夠了。

2、webpack.config.js:

歸根結底,webpack就是一個.js配置文件,咱們創建一個webpack.config.js文件,咱們能夠在其中進行各項配置。

好比咱們想要使用一個熱加載網頁的框架webpack-dev-server(webpack-dev-server是一個輕量級的服務器,修改文件源碼後,自動刷新頁面將修改同步到頁面上),咱們先安裝:

npm install webpack@4.6.0 webpack@2.0.15 webpack-dev-server@3.1.3 --save-dev

而後在package.json的"scripts"裏增長一個快速啓動webpack-dev-server服務的腳本:

"scripts": { "dev": "webpack-dev-server --open --config webpack.config.js" },

 package.json的詳細配置以下:

{
  "name": "test13", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", "dev": "webpack-dev-server --open --config webpack.config.js" }, "author": "", "license": "ISC", "devDependencies": { "webpack": "^4.6.0", "webpack-cli": "^2.0.15", "webpack-dev-server": "^3.1.3" } }

在webpack.config.js中對webpack.config.js中添加devServer選項對webpack-dev-server進行詳細配置:

devServer:{
        port: 3000,
        publicPath: "./"
    }

 webpack.config.js的詳細配置以下:

var webpack = require('webpack'); var path = require('path'); // 引入node的path模塊 module.exports={ entry: { entry: './src/main.js' // 入口文件 }, output: { path: path.resolve(__dirname, 'dist'), // 打包路勁(獲取絕對路徑) filename: 'bundle.js' // 打包文件 }, module: {}, plugins: [], devServer: { open: true, port: 8080 } }

當運行:

npm run dev

命令時,就會執行

webpack-dev-server --open --config webpack.config.js

其中--config是指向webpac-dev-server讀取的配置文件路徑,這裏直接讀取咱們在上一步建立的webpack.config.js文件。

--open會在執行命令時自動在瀏覽器中打開頁面,默認地址是127.0.0.1:8080,不過ip和端口都是能夠配的:

webpack配置中最重要的也是必選的兩項是入口和出口,入口的做用是告訴webpack從哪裏開始尋找依賴,而且編譯。出口則用來配置編譯後的文件存儲位置和文件名。

在終端執行

npm run dev

就會自動在瀏覽器中打開頁面了。

3、完善配置文件:

在webpack的世界裏,每個文件都是一個模塊,好比.css,.js,.html,.jpg,.less等。對於不一樣的模塊,須要用不一樣的加載器來處理,而加載器就是webpack最重要的功能。經過安裝不一樣的加載器能夠對各類不一樣後綴名的文件進行處理,好比如今要寫一個css樣式,就要用到css-loader和style-loader。用npm方式安裝它:

npm install css-loader --save-dev
npm install style-loader --save-dev

安裝完成後,在webpack.config.js文件裏配置Loader,增長對.css文件的處理:

module: {
    rules: [
      {
        test: /\.css$/,
        use: [
                'style-loader',
                'css-loader'
            ]
      }
    ]
  }

webpack看似複雜,但它不過是一個js配置文件,只要搞清楚入口、出口、加載器、插件這四個概念,使用起來就不那麼困惑了。

4、Loaders

Loaders是webpack提供的最激動人心的功能之一了。經過使用不一樣的loader,webpack有能力調用外部的腳本或工具,實現對不一樣格式的文件的處理,好比說分析轉換scss爲css,或者把下一代的JS文件(ES6,ES7)轉換爲現代瀏覽器兼容的JS文件,對React的開發而言,合適的Loaders能夠把React的中用到的JSX文件轉換爲JS文件。

Loaders須要單獨安裝而且須要在webpack.config.js中的modules關鍵字下進行配置,Loaders的配置包括如下幾方面:

test:一個用以匹配loaders所處理文件的拓展名的正則表達式(必須)

loader:loader的名稱(必須)

include/exclude:手動添加必須處理的文件(文件夾)或屏蔽不須要處理的文件(文件夾)(可選);
query:爲loaders提供額外的設置選項(可選)

下面以css的處理爲例來講明:

一、以es6方式導入文件:

如今寫一些css,就須要用到style-loader和css-loader,如今經過npm來安裝:

npm install css-loader style-loader --save-dev

安裝完成後,創建一個css文件:

body { background: pink; }

在main.js文件中增長以下代碼:

import css from './app.css'; console.log("hello world");

從新執行: 

npm run build

文件夾結構以下:

其中,app.css:

body { background: pink; }

app.js:

import css from './app.css'; console.log("hello world");

 index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./dist/bundle.js"></script> </head> <body> </body> </html>

package.json:

{
  "name": "test16", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^2.1.0", "style-loader": "^0.23.1", "webpack": "^3.6.0" } } 

 webpack.config.js:

var webpack = require('webpack'); var path = require('path'); // 引入node的path模塊 module.exports={ entry: { entry: './src/app.js' // 入口文件 }, output: { path: path.resolve(__dirname, 'dist'), // 打包路勁(獲取絕對路徑) filename: 'bundle.js' // 打包文件 }, module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] } ] }, plugins: [], devServer: {}, }

二、以commonJS方式導入文件:

文件目錄:

package.json:

{
  "name": "test25", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack --config webpack.config.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^2.1.0", "style-loader": "^0.23.1", "webpack": "^3.6.0" } } 

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div> <script src="./dist/bundle.js"></script> </body> </html>

 show.js:

function show(content){ document.getElementById("app").innerText = "hello " + content; } module.exports = show;

style.css:

body{ background: pink; } #app{ text-align: center; }

 main.js:

const style = require("./style.css"); const show = require("./show.js"); show("webpack");

webpack.config.js:

const path = require("path"); module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: 'bundle.js' }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"] } ] }, plugins: [], devServer: {} }; 

 5、Babel

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

讓你能使用最新的JavaScript代碼(ES6,ES7...),而不用管新標準是否被當前使用的瀏覽器徹底支持;

讓你能使用基於JavaScript進行了拓展的語言,好比React的JSX;

Babel的安裝與配置

Babel實際上是幾個模塊化的包,其核心功能位於稱爲babel-core的npm包中,webpack能夠把其不一樣的包整合在一塊兒使用,對於每個你須要的功能或拓展,你都須要安裝單獨的包(用得最多的是解析Es6的babel-env-preset包和解析JSX的babel-preset-react包)。

項目目錄結構以下:

package.json:

{
  "name": "test26", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack --config webpack.config.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.25.0", "babel-loader": "^7.1.1", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.5.2", "babel-preset-es2015": "^6.24.1", "webpack": "^3.0.0" } } 

在webpack中配置Babel的方法以下:

const path = require("path"); module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: 'bundle.js' }, module: { rules: [ { test: /\.js$/, loader: "babel-loader" } ] }, plugins: [ ], devServer: {} }; 

如今你的webpack的配置已經容許你使用ES6以及JSX的語法了。

show.js:

function show(content){ document.getElementById("app").innerText = "hello, " + content; } module.exports = show;

main.js:

let name = "webpack!" const show = require("./show.js"); show(name);

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="./dist/main_2d6cab1e.css"/> </head> <body> <div id="app"></div> <script src="./dist/bundle.js"></script> </body> </html>

其中的style.css文件無關緊要。

Babel其實能夠徹底在 webpack.config.js 中進行配置,可是考慮到babel具備很是多的配置選項,在單一的webpack.config.js文件中進行配置每每使得這個文件顯得太複雜,所以一些開發者支持把babel的配置選項放在一個單獨的名爲 ".babelrc" 的配置文件中。

6、手動經過終端方式,將第三方庫直接打包:

以jquery爲例:

在對應的文件夾下安裝jquery:

npm install jquery --save-dev

在main.js中導入jquery:

var $ = require('jquery');

導入後就能夠開始使用了:

// main.js var $ = require('jquery'); document.write('<div>Hello World</div>'); $("div").html("導入jquery實例!");

文件夾結構及文件內容以下方式一:

package.json:

{
  "name": "test15", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack src/main.js dist/bundle.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "jquery": "^3.3.1", "webpack": "^3.6.0" } } 

main.js:

var $ = require('jquery'); document.write('<div>Hello World</div>'); $("div").html("導入jquery實例!");

 index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./dist/bundle.js"></script> </head> <body> </body> </html>

方式二:

package.json:

{
  "name": "test15", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "jquery": "^3.3.1", "webpack": "^3.6.0" } } 

webpack.config.js:

var webpack = require('webpack'); var path = require('path'); // 引入node的path模塊 module.exports={ entry: { entry: './src/main.js' // 入口文件 }, output: { path: path.resolve(__dirname, 'dist'), // 打包路勁(獲取絕對路徑) filename: 'bundle.js' // 打包文件 }, module: {}, plugins: [], devServer: {}, }

 main.js:

var $ = require('jquery'); document.write('<div>Hello World</div>'); $("div").html("導入jquery實例!");

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./dist/bundle.js"></script> </head> <body> </body> </html>

 7、一切皆模塊

Webpack有一個不可不說的優勢,它把全部的文件都都當作模塊處理,JavaScript代碼,CSS和fonts以及圖片等等經過合適的loader均可以被處理。

CSS

webpack提供兩個工具處理樣式表,css-loader 和 style-loader,兩者處理的任務不一樣,css-loader使你可以使用相似@import 和 url(...)的方法實現 require()的功能,style-loader將全部的計算後的樣式加入頁面中,兩者組合在一塊兒使你可以把樣式表嵌入webpack打包後的JS文件中。

//安裝 npm install --save-dev style-loader css-loader

8、插件(Plugins)

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

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

使用插件的方法

要使用某個插件,咱們須要經過npm安裝它,而後要作的就是在webpack配置中的plugins關鍵字部分添加該插件的一個實例(plugins是一個數組)

下面來看一個實例:經過Plugin將注入bundle.js文件裏的css提取到單獨的文件中

項目目錄以下:

app.css:

body { background: pink; } #app{ text-align: center; }

show.js:

function show(content){ document.getElementById("app").innerText = "hello " + content; } module.exports = show;

app.js:

require("./app.css"); const show = require("./show.js"); show("Webpack!");

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div> <script src="./dist/bundle.js"></script> </body> </html>

package.json:

{
  "name": "test22", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack --config webpack.config.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^2.1.0", "extract-text-webpack-plugin": "^3.0.2", "style-loader": "^0.23.1", "webpack": "^3.6.0" } } 

webpack.config.js:

const path = require('path'); // 引入node的path模塊 const ExtractTextPlugin = require ('extract-text-webpack-plugin'); module.exports={ // JavaScript 執行入口文件 entry: { entry: './src/app.js' // 入口文件 }, output: { // 將輸出文件都放到 dist 目錄下 path: path.resolve(__dirname, './dist'), // 將全部依賴的模塊合併輸出到一個bundle.js文件中 filename: 'bundle.js' }, module: { rules: [ { // 用正則去匹配要用該 loader 轉換的 css 文件 test: /\.css$/, loaders: ExtractTextPlugin.extract({ // 轉換.css文件須要使用的Loader use: ['css-loader'], }), } ] }, plugins: [ new ExtractTextPlugin({ // 從.js文件中提取出來的.css文件的名稱 filename:'[name]_[contenthash:8].css', }), ], devServer: {}, }

要讓以上代碼運行起來,須要先安裝新引入的插件:

npm i -D extract-text-webpack-plugin

安裝成功後從新執行構建, 咱們會發現 dist 目錄下多出一個entry_23c6115b.css 文件, bundle .j s 文件裏也沒有 css 代碼了,再將該 css 文件引入 index.html 裏就完成了。

從以上代碼能夠看出, Webpack是經過 plugins屬性來配置須要使用的插件列表的。plugins 屬性是一個數組,裏面的每一項都是插件的一個實例,在實例化一個組件時能夠經過構造函數傳入這個組件支持的配置屬性。

例如,ExtractTextPlugin插件的做用是提取出JavaScript代碼裏的css到一個單獨的文件中。對此咱們能夠經過插件的filename屬性,告訴插件輸出的css文件名稱是經過[name][contenthash:8] .css字符串模板生成的,裏面的[ name]表明文件的名稱,[contenthash:8]表明根據文件內容算出的8位Hash值,還有不少配置選項能夠在
ExtractTextPlugin ( https://github.com/webpack-contrib/extract-text-webpack-plugin )的主頁上查到。

9、使用DevServer:

實際開發中咱們可能會須要:

• 提供 HTTP 服務而不是使用本地文件預覽;
• 監昕文件的變化並自動刷新網頁,作到實時預覽:
• 支持 Source Map ,以方便調試。

對於這些, Webpack 都爲咱們考慮好了。 Webpack 原生支持上述第 2 、 3 點內容,再結合官方提供的開發工具 DevServer ( https://webpack乒org/configuration/dev-server/)也能夠很方便地作到第 1 點。 DevServer 會啓動一個 HTTP 服務器用於服務網頁請求,同時會幫助啓動Webpack,並接收 Webpack 發出的文件更變信號,經過 WebSocket 協議自動刷新網頁作到實時預覽。

下面在一個小項目中集成DevServer。

項目目錄以下:

app.css:

body { background: pink; } #app{ text-align: center; }

app.js:

require("./app.css"); const show = require("./show.js"); show("Webpack!");

 show.js:

function show(content){ document.getElementById("app").innerText = "hello " + content; } module.exports = show;

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div> <script src="./dist/bundle.js"></script> </body> </html>

 package.json:

{
  "name": "test23", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack --config webpack.config.js", "server": "webpack-dev-server --open" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^2.1.0", "extract-text-webpack-plugin": "^3.0.2", "style-loader": "^0.23.1", "webpack": "^3.6.0", "webpack-dev-server": "^2.9.1" } } 

首先須要安裝 DevServer:

cnpm i -D webpack-dev-server

webpack.config.js:

const path = require('path'); // 引入node的path模塊 const ExtractTextPlugin = require ('extract-text-webpack-plugin'); module.exports={ // JavaScript 執行入口文件 entry: { entry: './src/app.js' // 入口文件 }, output: { // 將輸出文件都放到 dist 目錄下 path: path.resolve(__dirname, './dist'), // 將全部依賴的模塊合併輸出到一個bundle.js文件中 filename: 'bundle.js' }, module: { rules: [ { // 用正則去匹配要用該 loader 轉換的 css 文件 test: /\.css$/, loaders: ExtractTextPlugin.extract({ // 轉換.css文件須要使用的Loader use: ['css-loader'], }), } ] }, plugins: [ new ExtractTextPlugin({ // 從.js文件中提取出來的.css文件的名稱 filename:'[name]_[contenthash:8].css', }), ], devServer: {}, }

 安裝成功後執行 "webpack-dev- server"或"npm run server" 命令, DevServer 就啓動了,這時咱們會看到控制檯有一 串日誌輸出:

Project is running at http://localhost:8080/ webpack output is served from /

這意味着 DevServer 啓動的 HTTP 服務器監聽在 8080 端口, DevServer 啓動後會一直駐留在後臺保持運行 ,訪問這個網址,就能獲取項目根目錄下的 index.html 了。用瀏覽器打開這個地址時咱們會發現頁面空白,錯誤的緣由是./ dist/bundle.j s 加載 404了 。 同時咱們會發現並無文件輸出到 dist 目錄,緣由是 DevServer 會將 Webpack 構建出的文件保存在 內存中,在要訪問輸出的文件時,必須經過 HTTP 服務訪問。因爲 DevServer不會理會 webpack .config.j s 裏配置的 output .path 屬性,因此要獲取 bundle.js 的正確 URL 是 http: //loca lhost:8080/bundle.js,對應的 index.html 應該修改成:

<html>
<head>
<meta charset= 」 UTF-8 」 >
</head>
<body>
<div id=」 app 」></ div>
〈 !一導入 DevServer 輸出的 JavaScript 文件一〉
<script src=」bundle.js"></script>
</body>
</ html>

模塊熱替換:

除了經過從新刷新整個網頁來實現實時預覽, DevServer 還有一種被稱做模塊熱替換的刷新技術。模塊熱替換能作到在不從新加載整個網頁的狀況下,經過將己更新的模塊替換老模塊,再從新執行一次來實現實時預覽。模塊熱替換相對於默認的刷新機制能提供更快的響應速度和更好的開發體驗。模塊熱替換默認是關閉的,要開啓模塊熱替換,咱們只 需在啓動DevServer 時帶上一 hot 參數,重啓 DevServer 後再去更新文件就能體驗到模塊熱替換的神奇了。 

支持 Source Map:

在瀏覽器中運行的 JavaScript 代碼都是編譯器輸出的代碼,這些代碼的可讀性不好。若是在開發過程當中遇到一個不知道緣由的 Bug,則咱們可能須要經過斷點調試去找出問題。在編譯器輸出的代碼上進行斷點調試是一件辛苦和不優雅的事情,調試工具能夠經過 Source Map( https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/)映射代碼,讓咱們在源代碼上斷點調試。 Webpack 支持生成 Source Map,只需在啓動時帶上一 devtool source-map參數。重啓 DevServer 後刷新頁面,再打開 Chrome 瀏覽器的開發者工具,就能夠在 Sources欄中看到可調試的源代碼了,如圖1-2所示。

相關文章
相關標籤/搜索