webpack學習
一、初識webpack
? 我們已經(jīng)知道了模塊化開發(fā)是非常重要和必要的了巾腕,而且也了解了一些前端模塊化的方案:AMD、CMD混移、CommonJS祠墅、ES6.
? 在ES6之前,要是想使用上面那些模塊化開發(fā)的方案歌径,那就必須得依靠一些對這些方案有底層支撐的一些工具,因為ES5的語法中根本就沒這些東西亲茅,我們需要有東西來對這些方案的語法進行解析回铛。而且,在模塊化開發(fā)完成之后還要進行一個整合和打包克锣,處理模塊間的依賴關(guān)系茵肃。一個項目中,有多個模塊進行導出和導入袭祟,關(guān)系會變得非常復雜验残,所以需要有工具幫我們處理一下這些依賴關(guān)系。
webpack處理模塊間依賴關(guān)系什么意思巾乳?
? 就是你只需要將一個入口的js文件進行打包您没,它會自動幫你找是否有依賴其它包,一層一層的處理下去然后打包成一個瀏覽器認識的js文件胆绊。
a.什么是打包氨鹏?
1.打包就是將各種資源模塊進行打包合并成一個或者多個包(Bundle)
2.對資源進行處理,比如說壓縮圖片压状,預處理Sass,less,將ES6語法轉(zhuǎn)成ES5的語法仆抵,將TypeScript轉(zhuǎn)成javascript等等
b.打包的工具有很多,像是grunt/gulp种冬,它們有什么不同镣丑?
1.grunt/gulp的核心是Task,通過配置一系列的task,定義task要處理的事務娱两,比如說壓縮圖片莺匠,預處理Sass,less,將ES6語法轉(zhuǎn)成ES5的語法,將TypeScript轉(zhuǎn)成javascript等等谷婆,然后讓grunt/gulp來依次執(zhí)行這些task慨蛙,讓整個流程自動化辽聊,所以grunt/gulp也被稱為前端自動化任務管理工具,它們強調(diào)的是前端流程的自動化期贫,模塊化不是它們的核心跟匆,也是通過配置一些東西,把模塊化作為一個task去處理而已通砍,而且會很復雜玛臂。
2.webpack更加強調(diào)模塊化開發(fā)的管理,官網(wǎng)解釋webpack就是一個現(xiàn)代的JavaScript應用的靜態(tài)模塊打包工具封孙,而壓縮圖片迹冤,預處理Sass,less,將ES6語法轉(zhuǎn)成ES5的語法,將TypeScript轉(zhuǎn)成javascript等等的功能只不過是它的附加功能虎忌。
二泡徙、安裝webpack
webpack對于模塊化開發(fā)很重要,所以就先安裝來使用吧
webpack要想運行需要依賴Node.js環(huán)境膜蠢。Node.js為了正常運行很多代碼堪藐,需要依賴各種包,所以它自帶了一個軟件包管理工具npm挑围。所以通過npm來安裝webpack礁竞。
webpack有兩種安裝方式
? 1.全局安裝,version是指定的版本 杉辙,-g表示全局安裝global
npm install webpack@version -g
? 2.局部安裝
cd 想要安裝的目錄
npm install webpack@version --save-dev
為什么全局安裝后模捂,還需要局部安裝呢?
- 在終端執(zhí)行webpack命令時蜘矢,使用的是全局安裝的webpack
- 當在package.json中定義了scripts時狂男,其中包含的webpack命令首先是找局部的webpack,找不到才用全局的硼端。
三并淋、webpack起步
現(xiàn)在可以進行模塊化開發(fā)了
mathUtil.js
function add(num1,num2) {
return num1 + num2;
}
function mul(num1,num2) {
return num1 * num2;
}
//CommonJS
module.exports = {
add,mul
};
main.js
//CommonJS
const {add,mul} = require("./mathUtil.js");
console.log("Hello webpack");
console.log(add(10, 20));
console.log(mul(10, 20));
//ES6
import * as author from "./author.js";
console.log(author.name);
console.log(author.age);
console.log(author.height);
author.js
//ES6
const name = "WaiGo";
const age = 20;
const height = 1.80;
export {
name,age,height
}
通過在終端輸入webpack指令進行打包,因為瀏覽器本身肯定不認識CommonJS
webpack main.js的地址 想要放入打包后的Js文件的地址
你會發(fā)現(xiàn)這里只是對main.js進行了打包珍昨,沒有管mathUtil.js和author.js县耽,webpack會自動找main.js中依賴了哪些模塊然后去進行一些處理的,這就是處理依賴關(guān)系镣典。
然后將打包好的js文件進行引入使用就可以了兔毙。
四、webpack.config.js配置和package.json配置
? 1.上面的webpack指令是不是挺麻煩的兄春,每次都要寫將哪里的入口文件打包到哪個出口文件澎剥,挺麻煩的,所以下面就通過webpack.config.js的配置文件實現(xiàn)我們只需要寫一個webpack指令赶舆,它就知道是把main.js給打包到bundle.js中哑姚。
module.exports = {
//需要打包的文件祭饭,入口JS文件
entry: "./src/main.js",
//1.入口文件可以直接寫當前路徑的main.js文件,直接寫相對路徑就可以叙量,
// 就是相對于webpack.config.js的路徑
//2.output是出口倡蝙,這需要一個對象
//包括這個輸出文件的地址path和文件名filename
//dist是distribute發(fā)布的意思
output: {
path:"./dist",
filename:"bundle.js"
}
};
注意這個path一定要是一個絕對路徑,寫相對路徑會報錯
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.output.path: The provided value "./dist" is not an absolute path!
錯誤信息說绞佩,這是無效的配置對象寺鸥,webpack在初始化的時候使用配置對象但是并沒有符合API schema的限制,因為"./dist"不是一個絕對路徑
const path = require("path");
module.exports = {
//需要打包的文件品山,入口JS文件
entry: "./src/main.js",
//1.入口文件可以直接寫當前路徑的main.js文件胆建,直接寫相對路徑就可以,
// 就是相對于webpack.config.js的路徑
//2.output是出口肘交,這需要一個對象
//包括這個輸出文件的地址path和文件名filename
//dist是distribute發(fā)布的意思
//3.path是一個絕對路徑笆载,那么肯定不要自己把它給寫死了,應該是動態(tài)獲取的
//Node里有個叫做path的模塊酸些,path就能拿到當前webpack.config.js的路徑
//所以要先下載這個依賴宰译。
// 1.想要使用Node里面的模塊,就必須先有個package.json文件魄懂,它是Node對
// 包進行管理需要用到的文件,先通過npm init來創(chuàng)建這個json文件
// 2.如果這個json文件中有一些依賴的話闯第,需要通過npm install來下載這些依賴
output: {
//__dirname(注意注意:這個dirname前面是有兩個下劃線的)是Node上下文的一個
// 全局變量市栗,保存著webpack.config.js這個文件的絕對路徑,path模塊中有個
// resolve方法可以進行路徑拼接咳短,就可以拼接出輸出絕對路徑了
path:path.resolve(__dirname,"dist"),
filename:"bundle.js"
}
};
五填帽、局部安裝webpack
我們之前使用的webpack是全局的webpack,可能我們的項目使用的webpack的版本和全局的版本不一致咙好,所以就要有個項目本地的webpack篡腌,然后把webpack指令映射到package.json中的scripts腳本中,這樣在使用npm run的指令的時候使用的就是項目本地的webpack而不是全局的webpack了勾效。
通過下面的指令安裝局部webpack
cd 到需要安裝的目錄
npm install webpack@version --save-dev
--save-dev表示是開發(fā)時依賴
npm官方鏡像安裝非常慢嘹悼,但是使用淘寶的cnpm就挺快的
npm install -g cnpm --registry=https://registry.npm.taobao.org
這樣就可以通過cnpm來替換npm下載了
六、配置package.json文件
將webpack指令映射成npm run build指令层宫,這樣才能使用本地的webpack而不是全局的webpack杨伙。不然就得寫這么一長串指令了
node_modules/.bin/webpack
就這樣配置映射
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"http://這就可以使用npm run build指令打包了
},
七、loader
webpack能夠把css,TypeScript等等的東西也當成一個模塊進行處理萌腿,這樣就不用引入很多文件了限匣,不過原始的webpack指令是沒辦法處理js之外的文件的,所以就需要loader來擴展webpack的功能毁菱。
使用步驟:
? 1.通過npm 安裝需要使用的loader
? 2.在webpack.config.js中的module關(guān)鍵字下進行配置
可以進入webpack官網(wǎng)中找到相應的loader進行學習用法
官網(wǎng)這樣解釋loader
loader 用于對模塊的源代碼進行轉(zhuǎn)換米死。loader 可以使你在
import
或"加載"模塊時預處理文件锌历。因此,loader 類似于其他構(gòu)建工具中“任務(task)”峦筒,并提供了處理前端構(gòu)建步驟的強大方法究西。loader 可以將文件從不同的語言(如 TypeScript)轉(zhuǎn)換為 JavaScript,或?qū)?nèi)聯(lián)圖像轉(zhuǎn)換為 data URL勘天。loader 甚至允許你直接在 JavaScript 模塊中import
CSS文件怔揩!
a.如何將css文件打包
-
style-loader
將模塊的導出作為樣式添加到 DOM 中 -
css-loader
解析 CSS 文件后,使用 import 加載脯丝,并且返回 CSS 代碼
需要這兩個loader,先安裝
cnpm install style-loader --save-dev
cnpm install css-loader --save-dev
在webpack.config.js文件中進行配置
module: {
rules: [
{
test: /\.css$/,
//1.css-loader只負責css文件加載商膊,不會解析
//2.style-loader負責將樣式添加到DOM中
//使用多個loader時,webpack是從*右向左讀*的宠进,
// 若是沒使用css-loader解析就用style-loader會直接報錯
//所以順序不能亂
use: ['style-loader','css-loader' ]
}
]
}
編寫一個css文件并在main.js中導入
//導入css文件
require("./css/normal.css");
這時候使用npm run build就可以打包css了
若是沒有css-loader和style-loader打包css會報錯晕拆,說需要一些合適的loader才能打包。
b.如何打包less文件
打包less材蹬,除了上面的兩個loader之外還要一個less-loader和less(用來轉(zhuǎn)換less成css的工具)
同樣实幕,第一步安裝
cnpm install --save-dev less-loader less
第二步,配置
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
}
把這個加在modul的rules里面就可以了堤器,然后在入口文件中依賴less文件昆庇,然后打包就可以了。
c.如何進行圖片打包
? webpack把圖片也當作了模塊闸溃,而且不需要像引入css文件那樣使用import/require來導入整吆,如果在css中使用了就算是引用了。然后通過url-loader或者file-loader來打包辉川。
若是file-loader打包就會將這個圖片以32位哈希值為文件名拷貝一份放在dist文件夾下表蝙。
若是使用url-loader打包就會將圖片給轉(zhuǎn)換成base64的字符串。
使用url-loader還是file-loader是看的modul.rules里那個url-loader配置的options里的limit的閾值乓旗,大于就使用file-loader府蛇。若是使用file-loader就會在dist中產(chǎn)生一個新的名字的圖片。
所以需要安裝兩個loader,url-loader和file-loader
cd 對應目錄
npm install --save-dev url-loader
npm install --save-dev file-loader
配置一下url-loader就可以進行打包了屿愚,file-loader是不需要特別配置的汇跨,當圖片的大小超過url-loader的閾值后就自動使用file-loader了。
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//當加載的圖片小于limit時渺鹦,會將圖片編譯成base64的字符串形式
//當加載的圖片大于limit時扰法,就會去使用file-loader來加載
limit: 8196//文件的大小8kb
}
}
]
}
因為使用這個css文件的html文件沒有在dist中,那么它是加載不到這個圖片的毅厚,為了讓html文件能夠加載到這個圖片塞颁,我們需要對webpack.config.js文件里的output添加一個屬性publicPath:'dist/',這樣它在打包所有路徑的時候都會在前面先加一個這個屬性的值。這樣就找得到了。它原來會將圖片相對于dist文件夾的路徑返回放到圖片的地址那里祠锣,但是由于html文件在外面肯定找不到了
output: {
//__dirname(注意注意:這個dirname前面是有兩個下劃線的)是Node上下文的一個
// 全局變量酷窥,保存著webpack.config.js這個文件的絕對路徑,path模塊中有個
// resolve方法可以進行路徑拼接伴网,就可以拼接出輸出絕對路徑了
path:path.resolve(__dirname,"dist"),
filename:"bundle.js",
publicPath:"dist/"
}
打包圖片文件改名
默認使用file-loader產(chǎn)生的圖片名是像這樣子5c6dc1ca2516354142c5612a8021f9e4的一個32位的哈希值蓬推,但是開發(fā)人員可能就不知道是哪一張圖片了,那就需要對這個圖片進行我們想要的改名澡腾。
在url-loader的options里添加一個name屬性沸伏,值為"img/[name].[hash:8].[ext]"
img/:它會在dist中產(chǎn)生一個img文件夾
[name]:是Node中的一個語法,拿到原來圖片的名字
[hash:8]:是Node中的一個語法动分,取8位哈希值毅糟,他會自動運行哈希算法然后返回8位放在這里
[ext]:extension表示擴展名,這是拿到原來的擴展名
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//當加載的圖片小于limit時澜公,會將圖片編譯成base64的字符串形式
//當加載的圖片大于limit時姆另,就會去使用file-loader來加載
limit: 8196,//文件的大小8kb
name:"img/[name].[hash:8].[ext]"
}
}
]
}
d.ES6語法轉(zhuǎn)成ES5的處理
第一步:安裝
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
第二步:配置
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
exclude表示這些文件不進行壓縮
官網(wǎng)那種方式需要配置一個babel.rc文件,還沒學到就沒用了坟乾,就先用老師這種方式吧迹辐。
八、引入Vue.js
在webpack中甚侣,vue也是作為一個模塊來看待的明吩,所以是import Vue from "vue";這樣子來使用的,現(xiàn)在需要先把Vue給下載到項目本地殷费。由于Vue不只是開發(fā)時需要依賴贺喝,在運行時也是需要依賴的所以要指定為--save
nam install vue --save
使用
<div id="app">
{{message}}
</div>
<script src="dist/bundle.js"></script>
import Vue from "vue";
new Vue({
el:"#app",
data:{
message:"Hello Webpack~~~"
}
});
webpack中的Vue默認使用的是runtime-only的版本,這個是無法解析template的宗兼,需要runtime-complier版本,所以就報了下面這個錯誤氮采。這里老師沒仔細說這兩個版本的區(qū)別殷绍,到后面再補充。這里修改一下webpack的配置就可以使用了鹊漠。
bundle.js:1346 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
//在module.exports = {}中定義一個resolve
resolve:{
//別名
alias:{
//在import的時候會去這個文件夾中找
'vue$':"vue/dist/vue.esm.js"
}
}
九主到、el和template的區(qū)別
在之前學習Vue的過程中我們寫的代碼都是直接對vue實例對象掛載的那個div進行操作,都是在以后的開發(fā)中躯概,我們是不希望手動的頻繁去修改html文件中的東西的登钥。就是讓<div id="app"></div>這個掛載到vue實例對象中的DOM元素就這樣為空,但是我們又需要在在里面顯示東西娶靡,那應該怎么處理呢牧牢?
這就提到template屬性了,在vue實例中若是既定義了el屬性,也定義了template屬性塔鳍,那么在運行的時候template中的元素會將el掛載的那個元素完全給替換掉的伯铣。
new Vue({
el:"#app",
template:`
<div>
<h2>{{message}}</h2>
<button @click="btnClick">按鈕</button>
</div>
`,
data:{
message:"Hello Webpack~~~"
},
methods:{
btnClick() {
console.log("按鈕點擊了");
}
}
});
第一步升級:將template給抽離成一個組件,不然Vue實例中的代碼太多了
import Vue from "vue";
const app = {
template:`
<div>
<h2>{{message}}</h2>
<button @click="btnClick">按鈕</button>
</div>
`,
data(){
return {
message:"Hello Webpack~~~"
}
},
methods:{
btnClick() {
console.log("按鈕點擊了");
}
}
};
new Vue({
el:"#app",
template:`<app/>`,
components:{
app
}
});
第二步升級:把組件對象抽離到一個咱們放這個組件對象的文件中轮纫,這樣就好管理了
export default {
template:`
<div>
<h2>{{message}}</h2>
<button @click="btnClick">按鈕</button>
</div>
`,
data(){
return {
message:"Hello Webpack~~~"
}
},
methods:{
btnClick() {
console.log("按鈕點擊了");
}
}
}
這樣子使用
import Vue from "vue";
import App from "./vue/app.js";
new Vue({
el:"#app",
template:`<App/>`,
components:{
App
}
});
第三步升級:將template腔寡,js代碼分離
創(chuàng)建一個Vue Component文件,就是.vue文件
<!--模板-->
<template>
<div>
<h2 class = "title">{{message}}</h2>
<button @click="btnClick">按鈕</button>
</div>
</template>
<!--JS-->
<script>
export default {
name: "app",
data(){
return {
message:"Hello Webpack~~~"
}
},
methods:{
btnClick() {
console.log("按鈕點擊了");
}
}
}
</script>
<!--樣式-->
<style scoped>
.title{
color:lightgreen;
}
</style>
使用一個單獨的組件文件掌唾,代碼看起來是真的清爽啊放前。可是這樣子是打包不了的糯彬,因為webpack原先不能處理.vue文件凭语,所以要下載相應的loader
cnpm install --save-dev vue-loader vue-template-compiler
webpack.config.js配置
{
test: /\.vue$/,
use:['vue-loader']
}
這個指令會安裝最新的vue-loader,但是自從vue-loader14點幾的版本之后要想使用這個vue-loader還需要配置一個插件情连。不然就會報錯
Module build failed: Error: Cannot find module '@vue/component-compiler-utils'
若是不想要配置那個插件就得安裝一個小于14的版本叽粹,修改packege.json中的版本號后重新安裝。
"vue-loader": "^13.0.0",
然后重新安裝
cnpm install
現(xiàn)在就可以正常打包運行了却舀。這里說一下虫几,定義組件文件名的時候首字母最好大寫。
父子組件例子
子組件
<template>
<div>
<h2>我是標題</h2>
<p>我是共產(chǎn)主義接班人</p>
<h2>{{message}}</h2>
</div>
</template>
<script>
export default {
name: "Cpn",
data(){
return {
message : "馬克思主義萬歲"
}
}
}
</script>
<style scoped>
</style>
父組件
<!--模板-->
<template>
<div>
<h2 class = "title">{{message}}</h2>
<button @click="btnClick">按鈕</button>
<Cpn></Cpn>
</div>
</template>
<!--JS-->
<script>
import Cpn from "./Cpn.vue";
export default {
name: "app",
data(){
return {
message:"Hello Webpack~~~"
}
},
methods:{
btnClick() {
console.log("按鈕點擊了");
}
},
components:{
Cpn
}
}
</script>
<!--樣式-->
<style scoped>
.title{
color:lightgreen;
}
</style>
十挽拔、webpack中引用文件的擴展名的問題
如果覺得后綴名麻煩不想寫辆脸,可以在webpack.config.js中的resolve中配置一下extensions:[省略擴展名的文件類型]
resolve:{
//別名
alias:{
//在import的時候會去這個文件夾中找
'vue$':"vue/dist/vue.esm.js"
},
//后綴名
extensions:['.js','.less','.css','.vue']
}
不過有些時候是不能省略的,比如說在你指定的路徑螃诅,有個app.js和一個app.vue啡氢,那你寫個app,它不知道應該是哪一個术裸。
import Cpn from "./Cpn";
現(xiàn)在省略掉后綴名就不會報錯了
十一倘是、插件plugin
插件時用于對某個現(xiàn)有的架構(gòu)進行擴展的東西,webpack的插件就是用于對webpack本身的功能進行擴展袭艺。
plugin的使用和loader差不多搀崭,就是通過npm安裝后在webpack.config.js中進行一定的配置后就可以使用了。
-
添加版權(quán)的Plugin
在webpack.config.js中配置
const webpack = require("webpack"); module.exports = { ... plugins:[ new webpack.BannerPlugin('最終版權(quán)歸XXX所有') ] }
-
打包HTML的plugin
項目最終發(fā)布的時候只是發(fā)布dist中的內(nèi)容猾编,我們之前的打包都沒有把index.html文件給打包到dist文件夾中瘤睹,這樣dist中的html文件就沒有意義了。所以需要將index.html文件給打包到dist文件夾中答倡,這時需要使用HtmlWebpackPlugin 插件
功能:
- 自動生成一個index.html文件轰传,可以指定模板來生成
- 將打包的js文件,自動添加到生成的這html文件的body中瘪撇。
安裝:
cnpm install html-webpack-plugin --save-dev
-
js壓縮的plugin
在項目發(fā)布之前获茬,肯定需要對js等文件進行壓縮處理港庄,就是去掉空格啊,使用簡單的變量名替換原來的變量名這樣锦茁,就可以將文件的體積縮小攘轩。
第一步:安裝plugin
cnpm install uglifyjs-webpack-plugin@1.1.1 --save-dev
就是丑化js文件
這里指定版本1.1.1是為了符合webpack3.6.0,不然會報錯码俩,但是現(xiàn)在好像下載不了這個版本了度帮,最新的版本2點幾的又不能適配webpack3.6.0,所以我就先下載了最新的
cnpm install uglifyjs-webpack-plugin --save-dev
然后修改package.json中的版本號為1.1.1然后cpnm install去下載1點幾的版本稿存,然后就可以適配了笨篷,應該1.1.1不是一個穩(wěn)定的版本,老師下載的這個版本把橫幅插件的話給刪除了瓣履,但是這個版本沒有輸出率翅,還是打印了一行最終補全歸xxx所有,以后要是出現(xiàn)說版本不匹配的就可以降一下版本試試袖迎。
第二步:配置webpack.config.js
const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
...
plugins:[
new uglifyJsPlugin()
]
}
## 十二冕臭、搭建本地服務器
在前面的學習中,你肯定會發(fā)現(xiàn)燕锥,每次對main.js或者是什么進行了修改后想要驗證一下辜贵,都需要npm run build進行再次打包,然后才能驗證代碼是否準確归形。這大大降低了開發(fā)效率托慨,因為每次打包都是要把新的東西寫入硬盤的。所以暇榴,搭建一個本地開發(fā)服務器就非常重要了厚棵,webpack提供了一個可選的服務器。它能時時監(jiān)聽我們打包文件的代碼是否改變蔼紧,若是改變了它會自動編譯改變后的代碼婆硬,然后放在內(nèi)存中而不是直接寫入磁盤仑濒,因為內(nèi)存讀寫速度比磁盤快非常多秕重。
**安裝**:
> npm install --save-dev webpack-dev-server@2.9.1
這個服務器的版本和webpack的版本也有一定的對應關(guān)系,因為現(xiàn)在我的webpack是3.6.0暖眼,就要下載2.9.1
**配置:webpack.config.js**
```javascript
module.exports = {
...
devServer:{
contentBase:"./dist",
inline:true//是否實時刷新
}
}
啟動本地開發(fā)服務器的指令是
webpack-dev-server
但是在終端的話要在全局中定位到項目中webpack的地方才能使用這個指令哩至,代碼會是一大串。所以把這個指令映射到package.json中蜜自,就會自動去項目本地找了菩貌,而且只需要敲一段這種指令npm run dev
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"dev" : "webpack-dev-server"
},
使用npm run dev就能把本地開發(fā)服務器跑起來了,默認跑在8080端口重荠。然后你可以對main.js中的東西進行一些修改箭阶,你會發(fā)現(xiàn)瀏覽器會自動刷新你修改的內(nèi)容。但是這時候當服務器跑起來之后,你是需要手動去點擊連接才能打開瀏覽器的仇参,你可能想要它自動打開瀏覽器嘹叫,那就在dev指令后面加一個 --open
"dev" : "webpack-dev-server --open"
十三、webpack.config.js配置文件分離
我們之前只有一個webpack.config.js配置文件诈乒,但是在開發(fā)階段我們可能不想要進行一些打包操作罩扇,比如說Js代碼的丑化,這會使得我們代碼難以調(diào)試怕磨。所以現(xiàn)在就把原來的配置文件分成三份喂饥,一份是基本配置,一份是開發(fā)時配置肠鲫,一份是發(fā)布時配置员帮,這樣在不同時間將不同的兩份配置合并成一份配置文件就可以了。開發(fā)時就使用開發(fā)時配置合并基本配置导饲。
基本配置base.config.js
const path = require("path");
const webpack = require("webpack");
const htmlWebpackPlugin = require("html-webpack-plugin");
const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
//需要打包的文件捞高,入口JS文件
entry: "./src/main.js",
//1.入口文件可以直接寫當前路徑的main.js文件,直接寫相對路徑就可以渣锦,
// 就是相對于webpack.config.js的路徑
//2.output是出口硝岗,這需要一個對象
//包括這個輸出文件的地址path和文件名filename
//dist是distribute發(fā)布的意思
//3.path是一個絕對路徑,那么肯定不要自己把它給寫死了泡挺,應該是動態(tài)獲取的
//Node里有個叫做path的模塊辈讶,path就能拿到當前webpack.config.js的路徑
//所以要先下載這個依賴。
// 1.想要使用Node里面的模塊娄猫,就必須先有個package.json文件贱除,它是Node對
// 包進行管理需要用到的文件,先通過npm init來創(chuàng)建這個json文件
// 2.如果這個json文件中有一些依賴的話媳溺,需要通過npm install來下載這些依賴
output: {
//__dirname(注意注意:這個dirname前面是有兩個下劃線的)是Node上下文的一個
// 全局變量月幌,保存著webpack.config.js這個文件的絕對路徑,path模塊中有個
// resolve方法可以進行路徑拼接悬蔽,就可以拼接出輸出絕對路徑了
path:path.resolve(__dirname,"dist"),
filename:"bundle.js",
// publicPath:"dist/"
},
module: {
rules: [
{
test: /\.css$/,
//1.css-loader只負責css文件加載扯躺,不會解析
//2.style-loader負責將樣式添加到DOM中
//使用多個loader時,webpack是從右向左讀的蝎困,
// 若是沒使用css-loader解析就用style-loader會直接報錯
//所以順序不能亂
use: ['style-loader','css-loader']
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//當加載的圖片小于limit時录语,會將圖片編譯成base64的字符串形式
//當加載的圖片大于limit時,就會去使用file-loader來加載
limit: 8196,//文件的大小8kb
name:"img/[name].[hash:8].[ext]"
}
}
]
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test: /\.vue$/,
use:['vue-loader']
}
]
},
resolve:{
//別名
alias:{
//在import的時候會去這個文件夾中找
'vue$':"vue/dist/vue.esm.js"
},
//后綴名
extensions:['.js','.less','.css','.vue']
},
plugins:[
new webpack.BannerPlugin('最終版權(quán)歸XXX所有'),
new htmlWebpackPlugin({
template:'index.html'
})
],
};
開發(fā)時配置禾乘,因為只有開發(fā)時需要webpack-dev-server
module.exports = {
devServer:{
contentBase:"./dist",
inline:true
}
};
發(fā)布時依賴澎埠,只有發(fā)布時才需要Js丑化
const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
plugins:[
new uglifyJsPlugin()
],
};
為了合并配置文件,還需要一個工具始藕,webpack-merge
安裝:
cnpm install webpack-merge --save-dev
然后使用webpack-merge進行配置文件的合并
const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
const WebpackMerge = require("webpack-merge");
const baseConfig = require("./base.config");
module.exports = WebpackMerge(baseConfig,{
plugins:[
new uglifyJsPlugin()
],
});
const WebpackMerge = require("webpack-merge");
const baseConfig = require("./base.config");
module.exports = WebpackMerge(baseConfig,{
devServer:{
contentBase:"./dist",
inline:true
}
});
好的蒲稳,現(xiàn)在webpack.config.js可以退役了
const path = require("path");
const webpack = require("webpack");
const htmlWebpackPlugin = require("html-webpack-plugin");
const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
//需要打包的文件氮趋,入口JS文件
entry: "./src/main.js",
//1.入口文件可以直接寫當前路徑的main.js文件,直接寫相對路徑就可以江耀,
// 就是相對于webpack.config.js的路徑
//2.output是出口剩胁,這需要一個對象
//包括這個輸出文件的地址path和文件名filename
//dist是distribute發(fā)布的意思
//3.path是一個絕對路徑,那么肯定不要自己把它給寫死了祥国,應該是動態(tài)獲取的
//Node里有個叫做path的模塊昵观,path就能拿到當前webpack.config.js的路徑
//所以要先下載這個依賴。
// 1.想要使用Node里面的模塊系宫,就必須先有個package.json文件索昂,它是Node對
// 包進行管理需要用到的文件,先通過npm init來創(chuàng)建這個json文件
// 2.如果這個json文件中有一些依賴的話扩借,需要通過npm install來下載這些依賴
output: {
//__dirname(注意注意:這個dirname前面是有兩個下劃線的)是Node上下文的一個
// 全局變量椒惨,保存著webpack.config.js這個文件的絕對路徑,path模塊中有個
// resolve方法可以進行路徑拼接潮罪,就可以拼接出輸出絕對路徑了
path:path.resolve(__dirname,"dist"),
filename:"bundle.js",
// publicPath:"dist/"
},
module: {
rules: [
{
test: /\.css$/,
//1.css-loader只負責css文件加載康谆,不會解析
//2.style-loader負責將樣式添加到DOM中
//使用多個loader時,webpack是從右向左讀的嫉到,
// 若是沒使用css-loader解析就用style-loader會直接報錯
//所以順序不能亂
use: ['style-loader','css-loader']
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//當加載的圖片小于limit時沃暗,會將圖片編譯成base64的字符串形式
//當加載的圖片大于limit時,就會去使用file-loader來加載
limit: 8196,//文件的大小8kb
name:"img/[name].[hash:8].[ext]"
}
}
]
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test: /\.vue$/,
use:['vue-loader']
}
]
},
resolve:{
//別名
alias:{
//在import的時候會去這個文件夾中找
'vue$':"vue/dist/vue.esm.js"
},
//后綴名
extensions:['.js','.less','.css','.vue']
},
plugins:[
new webpack.BannerPlugin('最終版權(quán)歸XXX所有'),
new htmlWebpackPlugin({
template:'index.html'
}),
new uglifyJsPlugin()
],
devServer:{
contentBase:"./dist",
inline:true
}
};
不過現(xiàn)在直接打包的話會報錯的何恶,因為webpack默認的配置文件名為webpack.config.js孽锥,你把它刪除了,自然就報錯了细层,所以現(xiàn)在需要在package.json中配置一下webpack的配置文件的名字
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config ./build/prod.config.js",
"dev": "webpack-dev-server --open --config ./build/dev.config.js"
},
現(xiàn)在就可以打包了惜辑,不過還有個地方需要改
path:path.resolve(__dirname,"dist"),
--dirname表示配置文件當前的路徑,現(xiàn)在變成build文件夾疫赎,所以"dist"要改成"../dist"盛撑,表示到打包到build的上級目錄