webpack介紹和使用

一webpack介紹
1由來
2介紹
3做用
4拓展說明
5webpack總體認知
二webpack安裝
1安裝node
2安裝cnpm
3安裝nrm的兩種方法
4安裝webpack
三webpack配置
0搭建項目結構
1初始化一個項目會建立一個packagejson文件
2在當前的項目中安裝Webpack做爲依賴包
3當前項目結構
4實現CSS打包
5實現SCSS打包
6實現Less打包
7實現打包url資源圖片gif圖標等功能
8Webpack-dev-server結合後端服務器的熱替換配置
9ES6轉換爲ES5語法
10防止文件緩存生成帶有20位的hash值的惟一文件
11抽取CSS爲單獨文件
12開發環境和生產環境的分離
13在生產環境中配置代碼壓縮功能css

 

 

1、webpack介紹
一、由來
因爲前端以前js、css、圖片文件須要單獨進行壓縮和打包,這樣團隊人員處理很繁瑣,而後 Instagram 團隊就想讓這些工做自動化,而後webpack應運而生。html

二、介紹
webpack是一個模塊打包器(module bundler),webpack視HTML,JS,CSS,圖片等文件都是一種 資源 ,每一個資源文件都是一個模塊(module)文件,webpack就是根據每一個模塊文件之間的依賴關係將全部的模塊打包(bundle)起來。前端

三、做用
對 CommonJS 、 AMD 、ES6的語法作了兼容
對js、css、圖片等資源文件都支持打包(適合團隊化開發)
比方你寫一個js文件,另一我的也寫一個js文件,須要合併很麻煩,如今交給webpack合併很簡單
有獨立的配置文件webpack.config.js
能夠將代碼切割成不一樣的chunk,實現按需加載,下降了初始化時間
具備強大的Plugin(插件)接口,大可能是內部插件,使用起來比較靈活node

……webpack

 

四、拓展說明
CommonJS、AMD、CMD是用於JavaScript模塊管理的三大規範,CommonJS定義的是模塊的同步加載,是一個更偏向於服務器端的規範(也能夠在瀏覽器中使用),主要用於Nodejs,根據CommonJS規範,一個單獨的文件就是一個模塊,加載模塊使用require()方法,該方法讀取一個文件並執行,最後返回文件內部的exports對象。git

AMD和CMD則是定義模塊異步加載適用於瀏覽器端,都是爲了 JavaScript 的模塊化開發,(這裏說一下爲什要有異步加載,由於瀏覽器若是使用common.js同步加載模塊的話,就會致使性能等問題,因此針對這個問題,又出了一個規範,這個規範能夠實現異步加載依賴模塊)github

AMD規範會提早加載依賴模塊,AMD規範是經過requireJs 在推廣過程當中對模塊定義的規範化產出。(AMD 規範:https://github.com/amdjs/amdjs-api/wiki/AMD)web

CMD規範會延遲加載依賴模塊, CMD 規範是 SeaJs 在推廣過程當中對模塊定義的規範化產出。npm

(CMD規範:https://github.com/seajs/seajs/issues/242)json

AMD規範和CMD規範的區別

對於依賴的模塊,AMD 是提早執行,CMD 是延遲執行。不過 RequireJS 從 2.0 開始,也改爲能夠延遲執行(根據寫法不一樣,處理方式不一樣)
CMD 推崇依賴就近,AMD 推崇依賴前置
AMD 的 API 默認是一個當多個用,CMD 的 API 嚴格區分,推崇職責單一。好比 AMD 裏,require 分全局 require 和局部 require,都叫 require。CMD 裏,沒有全局 require,而是根據模塊系統的完備性,提供 seajs.use 來實現模塊系統的加載啓動。CMD 裏,每一個 API 都簡單純粹
webpack和gulp的區別

gulp是前端自動化構建工具,強調的是前端開發的工做流程,咱們能夠經過配置一系列的task,定義task處理的事情(代碼壓縮、合併、編譯、瀏覽器實時更新等),而後定義執行順序,來讓gulp執行這些task,從而構建項目的整個前端開發流程,自動化構建工具並不能把全部模塊打包到一塊兒,也不能構建不一樣模塊之間的依賴關係。
webpack是 JavaScript 應用程序的模塊打包器,強調的是一個前端模塊化方案,更側重模塊打包,咱們能夠把開發中的全部資源(圖片、js文件、css文件等)都當作模塊,經過loader(加載器)和plugins(插件)對資源進行處理,打包成符合生產環境部署的前端資源。

 

五、webpack總體認知

​ (1)、webpack的核心概念分爲 入口(Entry)、加載器(Loader)、插件(Plugins)、出口(Output);

入口(Entry):入口起點告訴 webpack 從哪裏開始,並根據依賴關係圖肯定須要打包的文件內容

加載器(Loader):webpack 將全部的資源(css, js, image 等)都看作模塊,可是 webpack 能處理的只是 JavaScript,所以,須要存在一個能將其餘資源轉換爲模塊,讓 webpack 能將其加入依賴樹中的東西,它就是 loader。loader用於對模塊的源代碼進行轉換。loader 可使你在 import 或」加載」模塊時預處理文件。所以,loader 相似於其餘構建工具中「任務(task)」,並提供了處理前端構建步驟的強大方法。

rules: [ 
{ 
test: /\.(js|jsx)$/, 
use: 'babel-loader' 
} 
] 

插件(Plugins):loader 只能針對某種特定類型的文件進行處理,而 plugin 的功能則更爲強大。在 plugin 中可以介入到整個 webpack 編譯的生命週期,Plugins用於解決 loader 沒法實現的其餘事情,也就是說loader是預處理文件,那plugin 就是後處理文件。

對loader打包後的模塊文件(bundle.js)進行二次優化處理,例如:代碼壓縮從而減少文件體積

提供輔助開發的做用:例如:熱更新(瀏覽器實時顯示)

plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new HtmlWebpackPlugin({template: './src/index.html'})
]

 

2、webpack安裝

一、安裝node

使用 node -v 命令檢查版本

二、安裝cnpm

https://cnpmjs.org/

npm install -g cnpm --registry=https://registry.npm.taobao.org

使用 cnpm -v 命令檢查版本

三、安裝nrm的兩種方法
https://www.npmjs.com/package/nrm

nrm能夠幫助咱們切換不一樣的NPM源的快捷開關,能夠切換的NPM源包括:npm,cnpm,taobao, rednpm, npmMirror , edunpm

第一種方法(因爲是外網訪問進行安裝,可能會被牆)
npm install -g nrm

第二種方法(國內的淘寶鏡像,訪問穩定,推薦)
cnpm install -g nrm

使用 nrm - V 命令檢查版本(注意這裏的 V 是大寫的)

使用nrm ls 命令能夠查看當前能夠能夠切換的 NPM源
使用 npm use cnpm 命令 指定要使用的哪一種NPM源

 

四、安裝webpack
全局安裝

npm install --global webpack 

在項目中安裝最新版本或特定版本,分別執行如下命令:

npm install --save-dev webpack 
npm install --save-dev webpack@<version> 

 

3、webpack配置

0、搭建項目結構

 

--src:代碼開發目錄,

--build:開發環境webpack編譯打包輸出目錄,一樣按照view、styles、js組織

--dist:生產環境webpack編譯打包輸出目錄,一樣按照view、styles、js組織

--node_modules:因此使用的nodeJs模塊

--package.json: 項目配置

--webpack.config.js: 開發環境webpack配置

--webpack.production.config.js: 生產環境webpack配置

 

一、初始化一個項目(會建立一個package.json文件)

npm init

二、在當前的項目中安裝Webpack做爲依賴包

npm install --save-dev webpack

說明:--save :將配置信息保存到package.json中,

同時 --save :也是項目生產環境,項目發佈以後還依賴的東西,保存在dependencies

例如:若是你用了 jQuery,因爲發佈以後仍是依賴jQuery,因此是dependencies

--save-dev :是項目開發環境依賴的東西,保存在devDependencies中

例如:寫 ES6 代碼,若是你想編譯成 ES5 發佈那麼 babel 就是devDependencies

四、實現CSS打包

npm install css-loader style-loader --save-dev
或者
cnpm install css-loader style-loader --save-dev

在src—>css目錄中新建main.css

css 
#first{ 
border: 1px solid red; 
} 

在webpack.config.js中配置相關的loader

const path = require('path');  // 首先要引入node.js中path 模塊,用於處理文件與目錄的路徑

// const 命令聲明一個只讀的常量,一旦聲明,值不能夠改變,改變會報錯;只聲明不賦值也會報錯
// 常量存儲的是一個不能夠變化的變量。
// 
module.exports = {
    entry:'./src/./js/main.js', // 指定入口文件
    output:{
        path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路徑目錄
        filename: 'bulid.js' // 制定出口文件的名稱
    },
    module:{
        rules:[
        // 在webpack2中,loaders 被替換成了 rules 其實就是loader的規則
            {
                test: /\.css$/,
                use: [ 'style-loader', 'css-loader' ]
                // test 說明了當前 loader 能處理那些類型的文件
                // use 則指定了 loader 的類型。
                // 注意:數組中的loader不能省略擴展名
            }
        ]
    }
}

在main.js中獲取css目錄中的main.css文件

// 一、獲取index.html中的dom對象
var first = document.getElementById('first');
var btn = document.getElementById('btn');
var two = document.getElementById('two');
var res = document.getElementById('res');
    btn.onclick = function(){
        var firstValue = parseFloat(first.value);
        var twoValue = parseFloat(two.value);
        //二、獲取 module1.js中的 sum函數
        //http://www.ruanyifeng.com/blog/2015/05/require.html
        var sum = require('./module1.js');
        res.value = sum(firstValue,twoValue);
    }

    // 三、獲取css目錄中的main.css文件
    require('../css/main.css');

在終端中輸入 webpack命令進行css文件打包

 

五、實現SCSS打包

在src目錄中新建 sass目錄–> scss1.scss

scss 
// scss1.scss文件 
$color:purple; 
#two{ 
border:1px solid $color; 
} 

安裝對應的loader

npm install sass-loader node-sass webpack --save-dev
或者
cnpm install sass-loader css-loader style-loader node-sass webpack --save-dev

在webpack.config.js中配置相關的loader

const path = require('path');  // 首先要引入node.js中path 模塊,用於處理文件與目錄的路徑

// const 命令聲明一個只讀的常量,一旦聲明,值不能夠改變,改變會報錯;只聲明不賦值也會報錯
// 常量存儲的是一個不能夠變化的變量。
// 
module.exports = {
    entry:'./src/./js/main.js', // 指定入口文件
    output:{
        path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路徑目錄
        filename: 'bulid.js' // 制定出口文件的名稱
    },
    module:{
        rules:[
        // 在webpack2中,loaders 被替換成了 rules 其實就是loader的規則
        //  實現 css 打包
            {
                test: /\.css$/,
                use: [ 'style-loader', 'css-loader' ]
                // test 說明了當前 loader 能處理那些類型的文件
                // use 則指定了 loader 的類型。
                // 注意:數組中的loader不能省略擴展名
            },
            {
                test: /\.scss$/,
                // 注意 是sass-loader ,不是 scss-loader
                use: [ 'style-loader', 'css-loader', 'sass-loader' ]
            }

        ]
    }
}

在js目錄中 main.js裏面引入 scss1.scss

// 一、獲取index.html中的dom對象

var first = document.getElementById('first');
var btn = document.getElementById('btn');
var two = document.getElementById('two');
var res = document.getElementById('res');

btn.onclick = function(){
    var firstValue = parseFloat(first.value);
    var twoValue = parseFloat(two.value);
    //二、獲取 module1.js中的 sum函數
    //http://www.ruanyifeng.com/blog/2015/05/require.html
    var sum = require('./module1.js');
    res.value = sum(firstValue,twoValue);
}

// 三、獲取css目錄中的main.css文件
require('../css/main.css');

// 四、獲取sass目錄中的scss1.scss文件
require('../sass/scss1.scss');

在終端中輸入 webpack命令進行scss文件打包

 

六、實現Less打包

安裝

cnpm install --save-dev
cnpm install less less-loder css-loader style-loader  webpack --save-dev
或者
cnpm install less-loader less --save-dev在webpack.config.js中配置相關的loader

在在src目錄中新建less目錄–> less1.less

@color:blue;
#res{

    border:1px dashed blue;
}

在webpack.config.js中配置相關的loader

const path = require('path');  // 首先要引入node.js中path 模塊,用於處理文件與目錄的路徑

// const 命令聲明一個只讀的常量,一旦聲明,值不能夠改變,改變會報錯;只聲明不賦值也會報錯
// 常量存儲的是一個不能夠變化的變量。
// 
module.exports = {
    entry:'./src/./js/main.js', // 指定入口文件
    output:{
        path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路徑目錄
        filename: 'bulid.js' // 制定出口文件的名稱
    },
    module:{
        rules:[
        // 在webpack2中,loaders 被替換成了 rules 其實就是loader的規則
            //  實現 css 打包
            {
                test: /\.css$/,
                use: [ 'style-loader', 'css-loader' ]
                // test 說明了當前 loader 能處理那些類型的文件
                // use 則指定了 loader 的類型。
                // 注意:數組中的loader不能省略擴展名
            },
            // 實現 scss 打包
            {
                test: /\.scss$/,
                // 注意 是sass-loader ,不是 scss-loader
                use: [ 'style-loader', 'css-loader', 'sass-loader' ]
            },
            // 實現 less 打包
            {
                test: /\.less$/,
                use: [ 'style-loader', 'css-loader', 'less-loader' ]
            }

        ]
    }
}

在js目錄中 main.js裏面引入 less1.less文件

js 
// 五、獲取less目錄中的less1.less文件 
require('../less/less1.less'); 
七、實現打包url資源(圖片、gif、圖標等)功能
  • 在src 目錄中 新建imgs目錄,放入兩張不一樣大小的圖片

  • 在index.html中新增 <div id="bg1"></div> <div id="bg2"></div>

  • 在mian.css中新增

// mian.css文件
#bg1{
    width: 200px;
    height: 200px;
    background: url('../imgs/bxg.jpg');
}

#bg2{
    width: 200px;
    height: 200px;
    background: url('../imgs/web.jpg') no-repeat;
}

前言

若是咱們但願在頁面引入圖片(包括img的src和background的url)。當咱們基於webpack進行開發時,引入圖片會遇到一些問題。

​ 其中一個就是引用路徑的問題。拿background樣式用url引入背景圖來講,咱們都知道,webpack最終會將各個模塊打包成一個文件,所以咱們樣式中的url路徑是相對入口html頁面的,而不是相對於原始css文件所在的路徑的。這就會致使圖片引入失敗。這個問題是用file-loader解決的,file-loader能夠解析項目中的url引入(不只限於css),根據咱們的配置,將圖片拷貝到相應的路徑,再根據咱們的配置,修改打包後文件引用路徑,使之指向正確的文件。

​ 另外,若是圖片較多,會發不少http請求,會下降頁面性能。這個問題能夠經過url-loader解決。url-loader會將引入的圖片編碼,生成dataURl。至關於把圖片數據翻譯成一串字符。再把這串字符打包到文件中,最終只須要引入這個文件就能訪問圖片了。固然,若是圖片較大,編碼會消耗性能。所以url-loader提供了一個limit參數,小於limit字節的文件會被轉爲DataURl,大於limit的還會使用file-loader進行copy。

​ url-loader和file-loader是什麼關係呢?簡答地說,url-loader封裝了file-loader。url-loader不依賴於file-loader,即便用url-loader時,只須要安裝url-loader便可,不須要安裝file-loader,由於url-loader內置了file-loader。經過上面的介紹,咱們能夠看到,url-loader工做分兩種狀況:1.文件大小小於limit參數,url-loader將會把文件轉爲DataURL;2.文件大小大於limit,url-loader會調用file-loader進行處理,參數也會直接傳給file-loader。所以咱們只須要安裝url-loader便可。

安裝

cnpm install
cnpm install url-loader file-loader --save-dev

在webpack.config.js中配置相關的loader

const path = require('path');  // 首先要引入node.js中path 模塊,用於處理文件與目錄的路徑

// const 命令聲明一個只讀的常量,一旦聲明,值不能夠改變,改變會報錯;只聲明不賦值也會報錯
// 常量存儲的是一個不能夠變化的變量。
// 
module.exports = {
    entry:'./src/./js/main.js', // 指定入口文件
    output:{
        path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路徑目錄
        filename: 'bulid.js' // 制定出口文件的名稱
        publicPath:'dist/'
        // path:全部輸出文件的目標路徑;
        // publicPath:輸出解析文件的目錄,url 相對於 HTML 頁面
    },
    module:{
        rules:[
        // 在webpack2中,loaders 被替換成了 rules 其實就是loader的規則
            //  實現 css 打包
            {
                test: /\.css$/,
                use: [ 'style-loader', 'css-loader' ]
                // test 說明了當前 loader 能處理那些類型的文件
                // use 則指定了 loader 的類型。
                // 注意:數組中的loader不能省略擴展名
            },
            // 實現 scss 打包
            {
                test: /\.scss$/,
                // 注意 是sass-loader ,不是 scss-loader
                use: [ 'style-loader', 'css-loader', 'sass-loader' ]
            },
            // 實現 less 打包
            {
                test: /\.less$/,
                use: [ 'style-loader', 'css-loader', 'less-loader' ]
            },
            // 實現 url 資源打包
            {
                // 圖片和字體文件使用 url-loader 來處理
                test: /\.(png|jpg|gif|ttf|eot|woff|woff2|svg)$/,
                use: [
                    {
                        loader: 'url-loader',
                        // options 爲能夠配置的選項
                        options: {
                            limit: 8192
                            // limit=8192表示將全部小於8kb的圖片都轉爲base64形式(爲何呢?由於一個很小的圖片,不值當的去發送一個請求,減小請求次                               數。)
                            // (其實應該說超過8kb的才使用 url-loader 來映射到文件,不然轉爲dataurl形式)
                        }
                    }
              ]
               //保證輸出的圖片名稱與以前命名的圖片名稱保持一致(目前只是支持這樣的寫法,webpack3 沒有響應的options進行配置)
             // use:'url-loader?limit=8192&name=imgs/[name].[ext]' 
          }

          ]
      }

在main.js中引入mui目錄中icons-extra.css的文件

// 五、獲取less目錄中的less1.less文件
require('../less/less1.less');

// 六、獲取src目錄中的mui目錄中icons-extra.css的文件
require('../mui/css/icons-extra.css');

Webpack-dev-server結合後端服務器的熱替換配置

webpack-dev-server提供了一個簡單的 web 服務器,而且可以實時從新加載(live reloading),同時把生成好的js和html構建到咱們的電腦內存中,這樣的話,即便咱們的目錄中沒有了相關js等文件,還可以加載出來,這樣可以提升咱們頁面運行速度。

安裝 webpack-dev-server 插件

// 先把以前依賴的包安裝
cnpm install
cnpm install webpack-dev-server --save-dev 
// webpack.config.js
 const path = require('path');  // 首先要引入node.js中path 模塊,用於處理文件與目錄的路徑
 // const 命令聲明一個只讀的常量,一旦聲明,值不能夠改變,改變會報錯;只聲明不賦值也會報錯
 // 常量存儲的是一個不能夠變化的變量。
 module.exports = {
     entry:'./src/./js/main.js', // 指定入口文件
     output:{
         path: path.resolve(__dirname, 'dist/js'), // 指定出口文件的路徑目錄
         filename: 'bulid.js' // 制定出口文件的名稱
     },
     module:{
         rules:[
         // 在webpack2中,loaders 被替換成了 rules 其實就是loader的規則
             //  實現 css 打包
             {
                 test: /\.css$/,
                 use: [ 'style-loader', 'css-loader' ]
                 // test 說明了當前 loader 能處理那些類型的文件
                 // use 則指定了 loader 的類型。
                 // 注意:數組中的loader不能省略擴展名
             },
             // 實現 scss 打包
             {
                 test: /\.scss$/,
                 // 注意 是sass-loader ,不是 scss-loader
                 use: [ 'style-loader', 'css-loader', 'sass-loader' ]
             },
             // 實現 less 打包
             {
                 test: /\.less$/,
                 use: [ 'style-loader', 'css-loader', 'less-loader' ]
             },
             // 實現 url 資源打包
             {
                 // 圖片文件使用 url-loader 來處理
                 test: /\.(png|jpg|gif|ttf)$/,
                 use: [
                 {
                     loader: 'url-loader',
                     // options 爲能夠配置的選項
                     options: {
                       limit: 8192
                       // limit=8192表示將全部小於8kb的圖片都轉爲base64形式
                       // (其實應該說超過8kb的才使用 url-loader 來映射到文件,不然轉爲data url形式)
                   }
               }
               ]
           }

           ]
       },
        devServer: {
         // contentBase: './dist', // 在 localhost:8080(默認) 下創建服務,將 dist 目錄下的文件,做爲可訪問文件  contentBase:告訴服務器從哪裏提供內容
         // 或者經過如下方式配置
         contentBase: path.join(__dirname, "dist"),
         compress: true,
         // 當它被設置爲true的時候對全部的服務器資源採用gzip壓縮
         // 對JS,CSS資源的壓縮率很高,能夠極大得提升文件傳輸的速率,從而提高web性能
         port: 9000, // 若是想要改端口,能夠經過 port更改
         hot: true, // 啓用 webpack 的模塊熱替換特性()
         inline: true, // 實現實時重載(實現自動刷新功能)默認狀況下是 true。
         host: "localhost" // 若是你但願服務器外部可訪問,指定使用一個 host。默認是 localhost(也就是你能夠不寫這個host這個配置屬性)。
     }
    }
// package.json
{
  "name": "mywebpack",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --open"
    // "start": "webpack-dev-server --open --port 8080 --hot --inline"  // 若是在這裏配置了,就不用在webpack.config.js中配置devServer屬性了。
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "css-loader": "^0.28.7",
    "file-loader": "^1.1.5",
    "html-webpack-plugin": "^2.30.1",
    "less": "^3.0.0-alpha.3",
    "less-loader": "^4.0.5",
    "node-sass": "^4.5.3",
    "sass-loader": "^6.0.6",
    "style-loader": "^0.19.0",
    "url-loader": "^0.6.2",
    "webpack": "^3.8.1",
    "webpack-dev-server": "^2.9.3"
  }
}

在命令行中運行 npm start,就會看到瀏覽器自動加載頁面。若是如今修改和保存任意源文件,web 服務器就會自動從新加載編譯後的代碼,可是打開後發現,打開的是 dist目錄,咱們想要的是 index.html顯示咱們的頁面,因此這是咱們還要藉助裏另外一個 html-webpack-plugin 插件。

html-webpack-plugin 簡單建立 HTML 文件,用於服務器訪問,其中包括使用script標籤的body中的全部webpack包。

安裝 html-webpack-plugin 插件]

cnpm install --save-dev html-webpack-plugin 

webpack.config.js配置

const path = require('path'); // 首先要引入node.js中path 模塊,用於處理文件與目錄的路徑
// const 命令聲明一個只讀的常量,一旦聲明,值不能夠改變,改變會報錯;只聲明不賦值也會報錯
// 常量存儲的是一個不能夠變化的變量。

// 引入html-webpack-plugin 插件
const HtmlWebpackPlugin = require('html-webpack-plugin');

const webpack = require('webpack');
module.exports = {
    entry: './src/./js/main.js', // 指定入口文件
    output: {
        path: path.resolve(__dirname, 'dist/js'), // 指定出口文件的路徑目錄
        filename: 'bulid.js' // 制定出口文件的名稱
    },
    module: {
        rules: [
            // 在webpack2中,loaders 被替換成了 rules 其實就是loader的規則
            //  實現 css 打包
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
                    // test 說明了當前 loader 能處理那些類型的文件
                    // use 則指定了 loader 的類型。
                    // 注意:數組中的loader不能省略擴展名
            },
            // 實現 scss 打包
            {
                test: /\.scss$/,
                // 注意 是sass-loader ,不是 scss-loader
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            // 實現 less 打包
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            },
            // 實現 url 資源打包
            {
                // 圖片文件使用 url-loader 來處理
                test: /\.(png|jpg|gif|ttf)$/,
                use: [{
                    loader: 'url-loader',
                    // options 爲能夠配置的選項
                    options: {
                        limit: 8192
                            // limit=8192表示將全部小於8kb的圖片都轉爲base64形式
                            // (其實應該說超過8kb的才使用 url-loader 來映射到文件,不然轉爲data url形式)
                    }
                }]
            }

        ]
    },
    devServer: {
        // contentBase: './dist', // 在 localhost:8080(默認) 下創建服務,將 dist 目錄下的文件,做爲可訪問文件  contentBase:告訴服務器從哪裏提供內容
        // 或者經過如下方式配置
        contentBase: path.join(__dirname, "dist"),
        port: 9000, // 若是想要改端口,能夠經過 port更改
        hot: true, // 啓用 webpack 的模塊熱替換特性()
        inline: true, // 實現實時重載(實現自動刷新功能)默認狀況下是 true。
        host: "localhost" // 若是你但願服務器外部可訪問,指定使用一個 host。默認是 localhost(也就是你能夠不寫這個host這個配置屬性)。
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: '首頁', // 用於生成的HTML文檔的標題
            filename: 'index.html', //寫入HTML的文件。默認爲index.html。也能夠指定一個子目錄(例如:)assets/admin.html
            template: 'index.html' // Webpack須要模板的路徑
        }),
        new webpack.HotModuleReplacementPlugin() // 須要結合 啓用熱替換模塊(Hot Module Replacement),也被稱爲 HMR
    ]
}

 

  • 再次使用npm start命令就能夠實現瀏覽器自動更新。

  • 問題來了,HtmlWebpackPlugin中的 title並無顯示出來,緣由是須要在定義的template模板中使用ejs語法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <!-- EJS 語法 
            /* EJS是一個簡單高效的模板語言,經過數據和模板,能夠生成HTML標記文本。能夠說EJS是一個JavaScript庫,EJS能夠同時運行在客戶端和服務器端,客戶端安裝直接引入文件便可 */
        -->
    <title><%= htmlWebpackPlugin.options.title%></title>
</head>

<body>
    <input type="text" id="first">
    <input type="button" id="btn" value="+">
    <input type="text" id="two">
    <input type="button" id="btn" value="=">
    <input type="text" id="res">
    <div id="bg1"></div>
    <div id="bg2"></div>
</body>
</html>

再次使用npm start命令就能夠啦。

 

九、ES6轉換爲ES5語法

安裝

cnpm install --save-dev babel-loader babel-core babel-preset-env

babel-core若是某些代碼須要調用Babel的API進行轉碼,就要使用babel-core模塊
babel-preset-env經過根據您的目標瀏覽器或運行時環境自動肯定您須要的Babel插件
babel 對一些公共方法使用了很是小的輔助代碼,好比 _extend。 默認狀況下會被添加到每個須要它的文件中,你能夠引入 babel runtime 做爲一個獨立模塊,來避免重複引入。

你必須執行 npm install babel-plugin-transform-runtime --save-dev 來把它包含到你的項目中,也要使用 npm install babel-runtime --save 把 babel-runtime 安裝爲一個依賴

配置

// 實現 url 資源打包
                    {
                        // 圖片文件使用 url-loader 來處理
                        test: /\.(png|jpg|gif|ttf)$/,
                        use: [{
                            loader: 'url-loader',
                            // options 爲能夠配置的選項
                            options: {
                                limit: 8192
                                    // limit=8192表示將全部小於8kb的圖片都轉爲base64形式
                                    // (其實應該說超過8kb的才使用 url-loader 來映射到文件,不然轉爲data url形式)
                            }
                        }]
                    },
                    // 實現 ES6轉 ES5
                    {
                        test: /\.js$/,
                        exclude: /(node_modules)/,  // exclude 排除的意思,把 node_modules文件夾排除編譯以外
                        use: {
                            loader: 'babel-loader',
                            options: {
                            // presets 預設列表(一組插件)加載和使用
                            presets: ['env'],
                            plugins: ['transform-runtime'] // 加載和使用的插件列表
                            }
                        }
                    }

 

把一些代碼改爲ES6 語法的寫法

// moudule1.js

function sum(x,y){
    return x + y;
}
// 導出 sum 函數
// module.exports = sum;
    // 改爲ES6 的寫法語法
export default{
    sum
}
// main.js

// 一、獲取index.html中的dom對象
var first = document.getElementById('first');
var btn1 = document.getElementById('btn1');
var two = document.getElementById('two');
var res = document.getElementById('res');
console.log(1);
btn1.onclick = function() {
    var firstValue = parseFloat(first.value);
    var twoValue = parseFloat(two.value);
    //二、獲取 module1.js中的 sum函數
    //http://www.ruanyifeng.com/blog/2015/05/require.html
    console.log(2);

    /* var sum = require('./module1.js');
     res.value = sum(firstValue,twoValue);*/
    res.value = sumObj.sum(firstValue, twoValue);
}

// 三、獲取css目錄中的main.css文件
// require('../css/main.css');

//  把步驟3 改成 ES6寫法,引入css目錄中的main.css文件
import '../css/main.css';

// 四、獲取sass目錄中的scss1.scss文件
require('../sass/scss1.scss');

// 五、獲取less目錄中的less1.less文件
require('../less/less1.less');

// 六、獲取src目錄中的mui目錄中icons-extra.css的文件
require('../mui/css/icons-extra.css');

// 把 var sum = require('./module1.js'); 寫成 ES6語法
import sumObj from './module1.js'

 

十、防止文件緩存(生成帶有20位的hash值的惟一文件)

// webpack.config.js

output: {
        path: path.resolve(__dirname, 'dist/js'), // 指定出口文件的路徑目錄
        // filename: 'bulid.js' // 制定出口文件的名稱
        filename: '[name].[hash].js' // 將入口文件重命名爲帶有20位的hash值的惟一文件
    }
十一、抽取CSS爲單獨文件
    • 安裝插件從 build.js文件中提取文本(CSS)到單獨的文件


      • npm install --save-dev extract-text-webpack-plugin 
    • 在webpack.config.js中配置

const path = require('path'); // 首先要引入node.js中path 模塊,用於處理文件與目錄的路徑
// const 命令聲明一個只讀的常量,一旦聲明,值不能夠改變,改變會報錯;只聲明不賦值也會報錯
// 常量存儲的是一個不能夠變化的變量。

// 引入html-webpack-plugin 插件
const HtmlWebpackPlugin = require('html-webpack-plugin');

const webpack = require('webpack');

const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
    entry: './src/./js/main.js', // 指定入口文件
    output: {
        path: path.resolve(__dirname, 'dist'), // 指定出口文件的路徑目錄
        // filename: 'bulid.js' // 制定出口文件的名稱
        // path指定了本地構建地址,publicPath指定在瀏覽器中所引用的,指定的是構建後在html裏的路徑
        // publicPath: './',
        // 將入口文件重命名爲帶有20位的hash值的惟一文件
        filename: '[name].[hash].js' 
    },
    module: {
        rules: [
            // 在webpack2中,loaders 被替換成了 rules 其實就是loader的規則
            //  實現 css 打包
            /*{
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
                    // test 說明了當前 loader 能處理那些類型的文件
                    // use 則指定了 loader 的類型。
                    // 注意:數組中的loader不能省略擴展名
            },*/
            // 實現 scss 打包
            {
                test: /\.scss$/,
                // 注意 是sass-loader ,不是 scss-loader
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            // 實現 less 打包
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            },
            // 實現 url 資源打包
            {
                // 圖片文件使用 url-loader 來處理
                test: /\.(png|jpg|gif|ttf)$/,
                use: [{
                    loader: 'url-loader',
                    // options 爲能夠配置的選項
                    options: {
                        limit: 8192
                            // limit=8192表示將全部小於8kb的圖片都轉爲base64形式
                            // (其實應該說超過8kb的才使用 url-loader 來映射到文件,不然轉爲data url形式)
                    }
                }]
               //保證輸出的圖片名稱與以前命名的圖片名稱保持一致(目前只是支持這樣的寫法,                   webpack3 沒有響應的options進行配置)
                // use:'url-loader?limit=8192&name=imgs/[name].[ext]' 
            },
            // 實現 ES6轉 ES5
            {
                test: /\.js$/,
                exclude: /(node_modules)/, // exclude 排除的意思,把 node_modules文件夾排除編譯以外
                use: {
                    loader: 'babel-loader',
                    options: {
                        // presets 預設列表(一組插件)加載和使用
                        presets: ['env'],
                        plugins: ['transform-runtime'] // 加載和使用的插件列表
                    }
                }
            },
            // 提取 css模塊(若是使用這個模塊的話,須要把以前的CSS打包模塊註釋掉,否則會重複)
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: "css-loader"
                })
            }

        ]
    },
    devServer: {
        // contentBase: './dist', // 在 localhost:8080(默認) 下創建服務,將 dist 目錄下的文件,做爲可訪問文件  contentBase:告訴服務器從哪裏提供內容
        // 或者經過如下方式配置
        contentBase: path.join(__dirname, "dist"),
        port: 9000, // 若是想要改端口,能夠經過 port更改
        hot: true, // 啓用 webpack 的模塊熱替換特性()
        inline: true, // 實現實時重載(實現自動刷新功能)默認狀況下是 true。
        host: "localhost" // 若是你但願服務器外部可訪問,指定使用一個 host。默認是 localhost(也就是你能夠不寫這個host這個配置屬性)。
    },
    plugins: [
        // 從 bundle 中提取文本(CSS)到單獨的文件      
        new ExtractTextPlugin({
            //  提取css,並重名爲帶有 20位的hash值的惟一文件
            filename: '[name].[hash].css',
            // 將全部的獨立文件模塊(這裏指的是css文件)合併成一個文件
            allChunks: true
        }),
        new HtmlWebpackPlugin({
            title: '首頁', // 用於生成的HTML文檔的標題
            filename: 'index.html', //寫入HTML的文件。默認爲index.html。也能夠指定一個子目錄(例如:)assets/admin.html
            template: 'index.html' // Webpack須要模板的路徑
                // template: 'index.ejs' // Webpack須要模板的路徑
        }),
        // 須要結合webpack-dev-server 啓用熱替換模塊(Hot Module Replacement),也被稱爲 HMR
        new webpack.HotModuleReplacementPlugin()
    ]
}

 

十二、開發環境和生產環境的分離

 

(1)開發環境與生產環境分離的緣由以下:

在開發環境中,咱們使用熱更新插件幫助咱們實現瀏覽器的自動更新功能,咱們的代碼沒有進行壓縮,若是壓縮了不方便咱們調試代碼等等,因此以上這些代碼不該出如今生產環境中。
生產環境中,咱們把項目部署到服務器時,咱們會對代碼進行各類各樣的優化,好比壓縮代碼等等,這時候咱們不該該把這些代碼放到開發環境中,不利於代碼開發和調試。

總結:針對以上這些說明,咱們頗有必要把區分開發環境與生產環境分離。

(2)開發環境的配置和生產換環境配置的區別。

開發環境有的配置,生產環境不必定有,好比說熱更新時使用到的HotModuleReplacementPlugin。

生產環境有的配置,開發環境不必定有,好比說用來壓縮js用的UglifyJsPlugin。

如何去作?

1> 由於webpack 默認找的是 webpack.config.js配置文件,因此要把開發環境的webpack.config.js配置文件改成webpack.dev.config.js表明開發環境的配置文件。

2> 新建一個webpack.prod.config.js,再把開發環境中的webpack.config.js複製進去(沒用的配置文件該刪除的刪除)

3> 修改package.json文件(在scripts 標籤中添加"dev"和"prod" 屬性配置)

js
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --config webpack.dev.config.js",
"prod": "webpack --config webpack.prod.config.js"
},
怎樣執行命令

執行開發環境的中配置
npm run dev
執行生產環境的中配置
npm run prod

1三、在生產環境中配置代碼壓縮功能
  • 配置webpack.prod.config.js 文件

/ webpack.prod.config.js

var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;

 // ……

   plugins: [

       // ……

        // js代碼 壓縮
        new UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    ]

執行 npm run prod 命令

 

 

 

原文:https://blog.csdn.net/it_cgq/article/details/78732970

相關文章
相關標籤/搜索