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"
}
}
npm
的start
命令是一個特殊的腳本名稱锅移,其特殊性表現(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的作用
通過使用不同的loader
,webpack
有能力調用外部的腳本或工具课舍,實現(xiàn)對不同格式的文件的處理塌西,比如說分析轉換scss
為css
,或者把下一代的JS文件(ES6筝尾,ES7)轉換為現(xiàn)代瀏覽器兼容的JS文件捡需,對React的開發(fā)而言,合適的Loaders
可以把React的中用到的JSX
文件轉換為JS文件筹淫。
配置Loaders
Babel
什么是Babel站辉?
Babel是一個編譯JavaScript的平臺
為什么要使用Babel?
- 讓你能使用最新的JavaScript代碼(ES6损姜,ES7...)饰剥,而不用管新標準是否被當前使用的瀏覽器完全支持;
- 讓你能使用基于JavaScript進行了拓展的語言摧阅,比如
React
的JSX
汰蓉;
Babel的安裝與配置
Babel其實是幾個模塊化的包,其核心功能位于稱為babel-core
的npm包中逸尖,webpack可以把其不同的包整合在一起使用古沥,對于每一個你需要的功能或拓展,你都需要安裝單獨的包(用得最多的是解析Es6的babel-preset-env
包和解析JSX
的babel-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-loader
和 style-loader
,二者處理的任務不同肃晚,css-loader
使你能夠使用類似@import
和 url(...)
的方法實現(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-loader
和 autoprefixer
(自動添加前綴的插件)
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是在打包構建過程中用來處理源文件的(JSX
,Scss
脑又,Less
..)暮胧,一次處理一個,插件并不直接操作單個文件问麸,它直接對整個構建過程其作用往衷。
使用插件的方法
要使用某個插件,我們需要通過npm
安裝它严卖,然后要做的就是在webpack配置中的plugins關鍵字部分添加該插件的一個實例席舍。(plugins是一個數(shù)組)
常用插件
HtmlWebpackPlugin
這個插件的作用是依據(jù)一個簡單的index.html
模板,生成一個自動引用你打包后的JS文件的新index.html
哮笆。這在每次生成的js文件名稱不同時非常有用(比如添加了hash值)来颤。
首先進行插件的安裝:
npm install --save-dev html-webpack-plugin
安裝完成之后,如果是依照以上教程流程部署環(huán)境的話稠肘,那么就得修改原先的項目結構:
- 移除
public
文件夾福铅,利用此插件,index.html
文件會自動生成项阴,此外CSS已經通過前面的操作打包到JS中了滑黔。 - 在app目錄下,創(chuàng)建一個
index.tmpl.html
文件模板,這個模板包含title
等必須元素略荡,在編譯過程中庵佣,插件會依據(jù)此模板生成最終的html頁面(如index.tmpl.html
),會自動添加所依賴的 css, js汛兜,favicon等文件巴粪。 - 在這之后,需要在
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"
})
]
};
- 新建一個build文件夾存放最終輸出文件(需要修改
webpack.config.js
)序无,然后再次運行npm start
就行了验毡。
這篇文章是我參考學習(copy)別人webpack入門教程的時候寫下的,寫時對文章內容還有不是很理解的地方帝嗡,需要之后再次閱讀。更加具體的內容請參考教程原文:zhangwang的webpack入門教程璃氢。