webpack入門學習筆記

webpack學習筆記

什么是Webpack砂豌?

WebPack可以看做是模塊打包機:它做的事情是愕秫,分析你的項目結構匹颤,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),并將其轉換和打包為合適的格式供瀏覽器使用模庐。

為什么要使用Webpack?

現(xiàn)今的很多網頁其實可以看做是功能豐富的應用油宜,它們擁有著復雜的JavaScript代碼和一大堆依賴包掂碱。為了簡化開發(fā)的復雜度,就出現(xiàn)了Webpack這種工具慎冤。

開始使用Webpack

安裝

①進行全局安裝

//全局安裝
npm install -g webpack

②在項目目錄中初始化

//初始化以生成package.js文件
npm init

③在項目目錄中局部安裝

// 局部安裝Webpack
npm install --save-dev webpack

④在項目目錄中新建兩個文件夾,app文件夾和public文件夾疼燥,app文件夾用來存放原始數(shù)據(jù)和我們將寫的JavaScript模塊,public文件夾用來存放之后供瀏覽器讀取的文件(包括使用webpack打包生成的js文件以及一個index.html文件)蚁堤。接下來我們再創(chuàng)建三個文件:

  • index.html --放在public文件夾中;
  • Greeter.js -- 放在app文件夾中;
  • main.js -- 放在app文件夾中;

⑤我們在index.html文件中寫入最基礎的html代碼醉者,它在這里目的在于引入打包后的js文件。(所引入js文件例如本例中的bundle.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>

⑦在Greeter.js中定義一個返回包含問候信息的html元素的函數(shù),并依據(jù)CommonJS規(guī)范導出這個函數(shù)為一個模塊:

// Greeter.js
module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = "Hi there and greetings!";
  //這是一個DOM元素
  return greet;
};

main.js文件中寫入下述代碼披诗,用以把Greeter模塊返回的節(jié)點插入頁面撬即。

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

正式使用Webpack

通過配置文件來使用Webpack

定義一個配置文件,這個配置文件其實也是一個簡單的JavaScript模塊呈队,我們可以把所有的與打包相關的信息放在里面剥槐。在項目的根目錄下新建一個名為webpack.config.js的文件,我們在其中寫入如下所示的簡單配置代碼:

module.exports = {
    //“__dirname”是node.js中的一個全局變量宪摧,它指向當前執(zhí)行腳本所在的目錄
    entry:  __dirname + "/app/main.js",//唯一入口文件
    output: {
        path: __dirname + "/public",//打包后的文件存放的地方
        filename: "bundle.js"http://打包后輸出文件的文件名
    }
}

有了這個配置之后粒竖,再打包文件,只需在終端里運行webpack(非全局安裝需使用node_modules/.bin/webpack)命令就可以了几于,這條命令會自動引用webpack.config.js文件中的配置選項蕊苗。

更快捷地執(zhí)行打包任務

npm可以引導任務執(zhí)行,對npm進行配置后可以在命令行中使用簡單的npm start命令來替代上面略微繁瑣的命令沿彭。在package.json中對scripts對象進行相關設置即可朽砰,設置方法如下:

{
  "name": "webpack-sample-project",
  "version": "1.0.0",
  "description": "Sample webpack project",
  "scripts": {
    "start": "webpack" // 修改的是這里,JSON文件不支持注釋,引用時請清除
  },
  "author": "zhang",
  "license": "ISC",
  "devDependencies": {
    "webpack": "3.10.0"
  }
}

npmstart命令是一個特殊的腳本名稱锅移,其特殊性表現(xiàn)在熔掺,在命令行中使用npm start就可以執(zhí)行其對于的命令,如果對應的此腳本名稱不是start非剃,想要在命令行中運行時,需要這樣用npm run {script name}npm run build推沸。

生成source maps(使調試更容易)

對小到中型的項目中备绽,eval-source-map是一個很好的選項,不過需要注意只應該開發(fā)階段使用它(對于打包后輸出的JS文件執(zhí)行具有性能和安全隱患)鬓催,我們繼續(xù)對上文新建的webpack.config.js肺素,進行如下配置:

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

使用webpack構建本地服務器(使得瀏覽器實時監(jiān)聽代碼修改,并自動刷新顯示修改后的結果)

webpack中進行配置之前需要單獨安裝本地開發(fā)服務器

npm install --save-dev webpack-dev-server

然后修改配置文件webpack.config.js

module.exports = {
  devtool: 'eval-source-map',

  entry:  __dirname + "/app/main.js",
  output: {
    path: __dirname + "/public",
    filename: "bundle.js"
  },

  devServer: {
    //端口port要是省略宇驾,默認為8080
    contentBase: "./public",//本地服務器所加載的頁面所在的目錄
    historyApiFallback: true,//不跳轉
    inline: true//實時刷新
  } 
}

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

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack",
    "server": "webpack-dev-server --open"
  },

Loaders

Loaders的作用

通過使用不同的loaderwebpack有能力調用外部的腳本或工具课舍,實現(xiàn)對不同格式的文件的處理塌西,比如說分析轉換scsscss,或者把下一代的JS文件(ES6筝尾,ES7)轉換為現(xiàn)代瀏覽器兼容的JS文件捡需,對React的開發(fā)而言,合適的Loaders可以把React的中用到的JSX文件轉換為JS文件筹淫。

配置Loaders

Babel

什么是Babel站辉?

Babel是一個編譯JavaScript的平臺

為什么要使用Babel?
  • 讓你能使用最新的JavaScript代碼(ES6损姜,ES7...)饰剥,而不用管新標準是否被當前使用的瀏覽器完全支持;
  • 讓你能使用基于JavaScript進行了拓展的語言摧阅,比如ReactJSX汰蓉;
Babel的安裝與配置

Babel其實是幾個模塊化的包,其核心功能位于稱為babel-core的npm包中逸尖,webpack可以把其不同的包整合在一起使用古沥,對于每一個你需要的功能或拓展,你都需要安裝單獨的包(用得最多的是解析Es6的babel-preset-env包和解析JSXbabel-preset-react包)娇跟。

// npm一次性安裝多個依賴模塊岩齿,模塊之間用空格隔開
npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-react

然后在webpack中配置Babel:

module.exports = {
    devtool: 'eval-source-map',

    //“__dirname”是node.js中的一個全局變量,它指向當前執(zhí)行腳本所在的目錄
    entry:  __dirname + "/app/main.js",//唯一入口文件
    output: {
        path: __dirname + "/public",//打包后的文件存放的地方
        filename: "bundle.js"http://打包后輸出文件的文件名
    },

    devServer:{
       contentBase:"./public",
       historyApiFallback:true,
        inline:true
    },

    module:{
        rules:[
            {
                //利用正則表達式匹配jsx和js格式文件
                test:/(\.jsx|\.js)/,
                use:{
                    loader:"babel-loader",
                    options:{
                        preset:[
                            //使得允許解析ES6和JSX語法
                            "env", "react"
                        ]
                    }
                },
                //不處理此文件夾下的文件
                exclude:/node_modules/
            }
        ]
    }
};

Babel其實可以完全在webpack.config.js中進行配置苞俘,但是考慮到babel具有非常多的配置選項盹沈,在單一的webpack.config.js文件中進行配置往往使得這個文件顯得太復雜,因此一些開發(fā)者支持把babel的配置選項放在一個單獨的名為 .babelrc 的配置文件中。

module.exports = {
    devtool: 'eval-source-map',

    //“__dirname”是node.js中的一個全局變量乞封,它指向當前執(zhí)行腳本所在的目錄
    entry:  __dirname + "/app/main.js",//唯一入口文件
    output: {
        path: __dirname + "/public",//打包后的文件存放的地方
        filename: "bundle.js"http://打包后輸出文件的文件名
    },

    devServer:{
       contentBase:"./public",
       historyApiFallback:true,
        inline:true
    },

    module:{
        rules:[
            {
                test:/(\.jsx|\.js)/,
                use:{
                    loader:"babel-loader"
                    //將options選項移至.babelrc中
                },
                exclude:/node_modules/
            }
        ]
    }
};
//.babelrc
{
  "presets": ["react", "env"]
}

CSS

CSS配置

webpack提供兩個工具處理樣式表做裙,css-loaderstyle-loader,二者處理的任務不同肃晚,css-loader使你能夠使用類似@importurl(...)的方法實現(xiàn) require()的功能,style-loader將所有的計算后的樣式加入頁面中锚贱,二者組合在一起使你能夠把樣式表嵌入webpack打包后的JS文件中。
首先進行安裝:

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

接著修改webpack.config.js中的配置文件:

module.exports = {
    devtool: 'eval-source-map',

    //“__dirname”是node.js中的一個全局變量关串,它指向當前執(zhí)行腳本所在的目錄
    entry:  __dirname + "/app/main.js",//唯一入口文件
    output: {
        path: __dirname + "/public",//打包后的文件存放的地方
        filename: "bundle.js"http://打包后輸出文件的文件名
    },

    devServer:{
       contentBase:"./public",
       historyApiFallback:true,
        inline:true
    },

    module:{
        rules:[
            {
                test:/(\.jsx|\.js)$/,
                use:{
                    loader:"babel-loader"
                    //將options選項移至.babelrc中
                },
                exclude:/node_modules/
            },
            {
                test:/\.css$/,
                use:[
                    {
                        loader:"style-loader"    
                    }, {
                        loader:"css-loader"
                    }
                ]
            }
        ]
    }
};

注意:我們這里例子中用到的webpack只有單一的入口拧廊,其它的模塊需要通過 import, require, url等與入口文件建立其關聯(lián)。

CSS module

被稱為CSS modules的技術意在把JS的模塊化思想帶入CSS中來晋修,通過CSS模塊吧碾,所有的類名,動畫名默認都只作用于當前模塊墓卦。(使CSS擁有局部作用域)
配置:

module.exports = {

    ...

    module:{
        rules:[
            {
                test:/(\.jsx|\.js)$/,
                use:{
                    loader:"babel-loader"
                    //將options選項移至.babelrc中
                },
                exclude:/node_modules/
            },
            {
                test:/\.css$/,
                use:[
                    {
                        loader:"style-loader"    
                    }, {
                        loader:"css-loader",
                        options:{
                            modules:true, //指定啟用css modules
                            localIdentName: '[name]__[local]--[hash:base64:5]' //指定css的類名格式
                        }
                    }
                ]
            }
        ]
    }
};

使用:
先將要使用的CSS文件引入倦春,例如:

import styles from './Greeter.css';

然后在需要使用的地方通過以下方式調用:

<div className={styles.root}> //使用cssModule添加類名的方法
CSS預處理器

首先安裝postcss-loaderautoprefixer(自動添加前綴的插件)

npm install --save-dev postcss-loader autoprefixer

接下來在webpack.config.js中添加postcss-loader

module.exports = {

    ...

    module:{
             rules:[
                 {
                     test:/(\.jsx|\.js)$/,
                     use:{
                         loader:"babel-loader"
                         //將options選項移至.babelrc中
                     },
                     exclude:/node_modules/
                 },
                 {
                     test:/\.css$/,
                     use:[
                         {
                             loader:"style-loader"    
                         }, {
                             loader:"css-loader",
                             options:{
                                 modules:true, //指定啟用css modules
                                 localIdentName: '[name]__[local]--[hash:base64:5]' //指定css的類名格式
                             }
                         }, {
                             loader:"postcss-loader"                    
                         }
                     ]
                 }
             ]
         }
};

再之后在根目錄新建postcss.config.js,并添加如下代碼之后,重新使用npm start打包落剪,css將會自動添加前綴睁本。

// postcss.config.js
module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}

插件(Plugins)

Plugins和Loaders的區(qū)別

Loaders和Plugins常常被弄混,但是他們其實是完全不同的東西著榴,可以這么來說添履,loaders是在打包構建過程中用來處理源文件的(JSXScss脑又,Less..)暮胧,一次處理一個,插件并不直接操作單個文件问麸,它直接對整個構建過程其作用往衷。

使用插件的方法

要使用某個插件,我們需要通過npm安裝它严卖,然后要做的就是在webpack配置中的plugins關鍵字部分添加該插件的一個實例席舍。(plugins是一個數(shù)組)

常用插件
HtmlWebpackPlugin

這個插件的作用是依據(jù)一個簡單的index.html模板,生成一個自動引用你打包后的JS文件的新index.html哮笆。這在每次生成的js文件名稱不同時非常有用(比如添加了hash值)来颤。
首先進行插件的安裝:

npm install --save-dev html-webpack-plugin

安裝完成之后,如果是依照以上教程流程部署環(huán)境的話稠肘,那么就得修改原先的項目結構:

  1. 移除public文件夾福铅,利用此插件,index.html文件會自動生成项阴,此外CSS已經通過前面的操作打包到JS中了滑黔。
  2. 在app目錄下,創(chuàng)建一個index.tmpl.html文件模板,這個模板包含title等必須元素略荡,在編譯過程中庵佣,插件會依據(jù)此模板生成最終的html頁面(如index.tmpl.html),會自動添加所依賴的 css, js汛兜,favicon等文件巴粪。
  3. 在這之后,需要在webpack.config.js中配置添加的插件:
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {

    ...
    
    module:{
             rules:[
                 {
                     test:/(\.jsx|\.js)$/,
                     use:{
                         loader:"babel-loader"
                         //將options選項移至.babelrc中
                     },
                     exclude:/node_modules/
                 },
                 {
                     test:/\.css$/,
                     use:[
                         {
                             loader:"style-loader"    
                         }, {
                             loader:"css-loader",
                             options:{
                                 modules:true, //指定啟用css modules
                                 localIdentName: '[name]__[local]--[hash:base64:5]' //指定css的類名格式
                             }
                         }, {
                             loader:"postcss-loader"                    
                         }
                     ]
                 }
             ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            //傳入相關參數(shù)
            template:__dirname + "/app/index.tmpl.html"
        })
    ]
};
  1. 新建一個build文件夾存放最終輸出文件(需要修改webpack.config.js)序无,然后再次運行npm start就行了验毡。

這篇文章是我參考學習(copy)別人webpack入門教程的時候寫下的,寫時對文章內容還有不是很理解的地方帝嗡,需要之后再次閱讀。更加具體的內容請參考教程原文:zhangwang的webpack入門教程璃氢。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末哟玷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子一也,更是在濱河造成了極大的恐慌巢寡,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件椰苟,死亡現(xiàn)場離奇詭異抑月,居然都是意外死亡,警方通過查閱死者的電腦和手機舆蝴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門谦絮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洁仗,你說我怎么就攤上這事层皱。” “怎么了赠潦?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵叫胖,是天一觀的道長。 經常有香客問我她奥,道長瓮增,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任哩俭,我火速辦了婚禮绷跑,結果婚禮上,老公的妹妹穿的比我還像新娘携茂。我一直安慰自己你踩,他們只是感情好,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著带膜,像睡著了一般吩谦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上膝藕,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天式廷,我揣著相機與錄音,去河邊找鬼芭挽。 笑死滑废,一個胖子當著我的面吹牛,可吹牛的內容都是我干的袜爪。 我是一名探鬼主播蠕趁,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辛馆!你這毒婦竟也來了俺陋?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤昙篙,失蹤者是張志新(化名)和其女友劉穎腊状,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苔可,經...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡缴挖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了焚辅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片映屋。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖法焰,靈堂內的尸體忽然破棺而出秧荆,到底是詐尸還是另有隱情,我是刑警寧澤埃仪,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布乙濒,位于F島的核電站,受9級特大地震影響卵蛉,放射性物質發(fā)生泄漏颁股。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一傻丝、第九天 我趴在偏房一處隱蔽的房頂上張望甘有。 院中可真熱鬧,春花似錦葡缰、人聲如沸亏掀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽滤愕。三九已至温算,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間间影,已是汗流浹背注竿。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留魂贬,地道東北人巩割。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像付燥,于是被迫代替她去往敵國和親宣谈。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內容

  • 最近在學習 Webpack,網上大多數(shù)入門教程都是基于 Webpack 1.x 版本的,我學習 Webpack 的...
    My_Oh_My閱讀 8,185評論 40 247
  • 無意中看到zhangwnag大佬分享的webpack教程感覺受益匪淺键科,特此分享以備自己日后查看蒲祈,也希望更多的人看到...
    小小字符閱讀 8,171評論 7 35
  • 采遍二月玫瑰的露水。 流盡世間癡情人的眼淚萝嘁。 在菩提樹下傾盡精髓 只求得再與你同醉終不悔 不負苦心一別千年今昔見 ...
    晚晴521閱讀 161評論 0 0
  • 最近工作之余覺得可以寫點東西然后貢獻出來,分享給大家⊙锞恚現(xiàn)在APP 都會用到第三方分享功能牙言,但是目前ShareSDK...
    ivylee_mr閱讀 2,069評論 0 2
  • 上大學的時候,在卷卷的推薦下看了《魁拔》這部動漫怪得,突然覺得國產動漫崛起有希望了咱枉,因此從這以后就喜歡上課這部動漫。...
    夏目心葉閱讀 805評論 2 4