Webpack前端技術(shù)類文章
前沿

webpack是前端打包工具,是大前端自動(dòng)化工廠的重要組成部分,webpack的主要是打包,webpack作為自動(dòng)化工具鏈的一部分集成更大的工具系統(tǒng),而不是將一切需求的實(shí)現(xiàn)都寄望于webpack。
wepack是前端一個(gè)工具,可以讓各個(gè)模塊進(jìn)行加載,預(yù)處理,再進(jìn)行打包,它能有Grunt或Gulp所有基本功能。
優(yōu)勢(shì):
支持commonJS和AMD模塊 支持很多模塊加載器的調(diào)用,可以使模塊加載器靈活定制,比如babel-loader加載器,該加載器能使我們使用ES6的語法來編寫代碼 可以通過配置打包成多個(gè)文件,有效的利用瀏覽器的緩存功能提升性能 使用模塊加載器,可以支持sass,less等處理器進(jìn)行打包且支持靜態(tài)資源樣式及圖片進(jìn)行打包
npm?install?-g?webpack
//?項(xiàng)目配置項(xiàng)
//?cd?打開
npm?init
package.json
{
?"name":?"jeskson",
?"version":?"1.0.0",
?"description":?"",
?"main":?"index.js",
?"scripts":?{
?????"test":?"echo?\"Error:?no?test?specified\"?&&?exit?1"
?},
?"author":?"",
?"license":?"ISC"
}
創(chuàng)建webpack的依賴項(xiàng):
npm?install?--save-dev?webpack
{
?"name":?"jeskson",
?"version":?"1.0.0",
?"description":?"",
?"main":?"index.js",
?"scripts":?{
?????"test":?"echo?\"Error:?no?test?specified\"?&&?exit?1"
?},
?"author":?"",
?"license":?"ISC",
?"devDependencies":?{
?????"webpack":?"^1.14.0"
?}
}
webpack的運(yùn)行方法
module.exports?=?{
?//?__dirname是nodejs里的一個(gè)全局變量
?//?它指向的是我們項(xiàng)目的根目錄
?//?入口文件的位置
?entry:?__dirname?+?'/app/main.js
?output:?{
?????//?打包后的文件放置的位置
?????path:?__dirname?+?'/public',
?????//?打包后我們的文件名字
?????filename:?'webpack.js'
?}
}
webpack.js
{
?"name":?"jeskson",
?"version":?"1.0.0",
?"description":?"",
?"main":?"index.js",
?"scripts":?{
?????"start":?"webpack",
?????"test":?"echo?\"Error:?no?test?specified\"?&&?exit?1"
?},
?"author":?"",
?"license":?"ISC",
?"devDependencies":?{
?????"webpack":?"^1.14.0"
?}
}
若start改da,npm?run?da
Loaders需要單獨(dú)安裝并且需要在webpack.config.js下的modules關(guān)鍵字下進(jìn)行配置,Loaders的配置選項(xiàng)包括以下幾方面:
test,一個(gè)匹配loaders所處理的文件的拓展名的正則表達(dá)式。 loader,loader的名稱 include/exclude,手動(dòng)添加必須處理的文件或屏蔽不需要處理的文件 query,為loaders提供額外的設(shè)置選項(xiàng)
npm?install?--save-dev?json-loader
webpack.config.js
module.exports?=?{
?//?__dirname是nodejs里的一個(gè)全局變量
?//?它指向的是我們項(xiàng)目的根目錄
?//?入口文件的位置
?entry:?__dirname?+?'/app/main.js
?output:?{
?????//?打包后的文件放置的位置
?????path:?__dirname?+?'/public',
?????//?打包后我們的文件名字
?????filename:?'webpack.js'
?},
?module:?{
?????loaders:?[
?????????{
?????????????test:?/\.josn$/,
?????????????loader:?'json"
?????????}
?????]
?}
}
work.js
var?config?=?require("./config.json")
document.write(config.text);
webpack對(duì)樣式表的操作
webpack提供兩個(gè)工具處理樣式表,css-loader和style-loader。
css-loader使你能夠使用類似@import和url(...)的方法實(shí)現(xiàn)require()的功能。
style-loader將所有的計(jì)算后的樣式加入頁面中,二者組合在一起使你能夠把樣式表嵌入webpack打包后的JS文件中。
安裝命令:npm install --save-dev style-loader css-loader
webpack.config.js
module.exports?=?{
?//?__dirname是nodejs里的一個(gè)全局變量
?//?它指向的是我們項(xiàng)目的根目錄
?//?入口文件的位置
?entry:?__dirname?+?'/app/main.js
?output:?{
?????//?打包后的文件放置的位置
?????path:?__dirname?+?'/public',
?????//?打包后我們的文件名字
?????filename:?'webpack.js'
?},
?module:?{
?????loaders:?[
?????????{
?????????????test:?/\.josn$/,
?????????????loader:?'json"
?????????},
?????????{
?????????????test:?/\.css$/,
?????????????loader:?"style!css"?//?右向左執(zhí)行
?????????}
?????]
?}
}
css3語法,編寫樣式的時(shí)候,要做瀏覽器的兼容,也就是要添加很多的樣式前綴,這樣也會(huì)增多代碼量,但是現(xiàn)在添加前綴的工作交給webpack來做。
npm?intall?--save-dev?postcss-loader?autoprefixer
webpack.config.js
module.exports?=?{
?//?__dirname是nodejs里的一個(gè)全局變量
?//?它指向的是我們項(xiàng)目的根目錄
?//?入口文件的位置
?entry:?__dirname?+?'/app/main.js
?output:?{
?????//?打包后的文件放置的位置
?????path:?__dirname?+?'/public',
?????//?打包后我們的文件名字
?????filename:?'webpack.js'
?},
?module:?{
?????loaders:?[
?????????{
?????????????test:?/\.josn$/,
?????????????loader:?'json"
?????????},
?????????{
?????????????test:?/\.css$/,
?????????????loader:?"style!css!postcss"?//?右向左執(zhí)行
?????????}
?????]
?},
?postcss:?[
?????require('autoprefixer')
?]
}
兼容:
body?{
?background:?red;
?display:?flex;
?display:?-webkit-box;
?display:?-ms-flexbox;
}
webpack之babel-core(es6轉(zhuǎn)換成es5)
Babel其實(shí)是幾個(gè)模塊化的包,其核心功能位于稱為babel-core的npm包中,不過webpack把它們整合在一起使用,但是對(duì)于每一個(gè)你需要的功能或拓展,你都需要安裝單獨(dú)的包(用得最多的是解析ES6的babel-preset-es2015包和解析JSX的babel-preset-react包)。
npm?install?--save-dev?babel-core?babel-loader?babel-preset-es2015?babel-preset-react
配置項(xiàng)寫法:
{
????test:?/\.js$/,
????exclude:?/node_modules/,
????loader:?'babel',?//?在webpack的module部分的loaders里進(jìn)行配置即可
????query:?{
????????presets:?['es2015','react']
????}
}
// React安裝:npm install --save react react-dom
webpack.config.js
module.exports?=?{
?//?__dirname是nodejs里的一個(gè)全局變量
?//?它指向的是我們項(xiàng)目的根目錄
?//?入口文件的位置
?entry:?__dirname?+?'/app/main.js
?output:?{
?????//?打包后的文件放置的位置
?????path:?__dirname?+?'/public',
?????//?打包后我們的文件名字
?????filename:?'webpack.js'
?},
?module:?{
?????loaders:?[
?????????{
?????????????test:?/\.josn$/,
?????????????loader:?'json"
?????????},
?????????{
?????????????test:?/\.css$/,
?????????????loader:?"style!css!postcss"?//?右向左執(zhí)行
?????????},
?????????{
?????????????test:?/\.js$/,
?????????????loader:?"babel",
?????????????exclude:?/node_modules/,
?????????????query:?{
?????????????????presets:?['es2015']
?????????????}
?????????}
?????]
?},
?postcss:?[
?????require('autoprefixer')
?]
}
webpack之插件的使用
插件(Plugins)是用來拓展Webpack功能的,它們會(huì)在整個(gè)構(gòu)建過程中生效,執(zhí)行相關(guān)的任務(wù)。
Loaders和Plugins常常被弄混,但是它們其實(shí)是完全不同的東西,loaders是打包構(gòu)建過程中用來處理源文件的 (JSX, Scss, Less),一次處理一次,插件并不直接操作單個(gè)文件,它直接對(duì)整個(gè)構(gòu)建過程起作用。
要使用某個(gè)插件,我們要通過npm安裝它,然后要做的就是在webpack配置中的plugins關(guān)鍵字部分,添加改插件的一個(gè)實(shí)例(plugins是一個(gè)數(shù)組),添加一個(gè)實(shí)現(xiàn)版權(quán)聲明的插件。
我們需要在配置文件的最開始調(diào)用webpack插件:
var?webpack?=?require('webpack');
然后在module.exports={}里添加一個(gè)plugins的關(guān)鍵字
plugins:?[
????new?webpack.BannerPlugin('版權(quán)')?//?在整個(gè)數(shù)組中new一個(gè)就可以了
????//?這里一個(gè)添加版權(quán)聲明的插件是webpack自帶的并不需要安裝插件
]
HtmlWebpackPlugin
這個(gè)插件的作用是依據(jù)一個(gè)簡(jiǎn)單的模板,幫你生成最終的HTML5文件,這個(gè)文件中自動(dòng)引用了你打包后的JS文件,每次編譯都在文件名中插入一個(gè)不同的哈希值。
npm?install?--save-dev?html-webpack-plugin
這個(gè)插件自動(dòng)完成了我們之前手動(dòng)做的一些事情,在正式使用之前需要對(duì)一直以來的項(xiàng)目結(jié)構(gòu)做一些改變:
移除public文件夾,利用此插件,HTML5文件會(huì)自動(dòng)生成,此外CSS已經(jīng)通過前面的操作打包到JS中,public文件夾里。
在app目錄下,創(chuàng)建一個(gè)Html文件模板,這個(gè)模板包含title等其它你需要的元素,在編譯過程中,本插件會(huì)依據(jù)此模板生成最終的html頁面,會(huì)自動(dòng)添加所依賴的css.js,favicon等文件。
配置項(xiàng):
webpack.config.js
var?webpack?=?require('webpack');
var?Html?=?require('html-webpack-plugin');
module.exports?=?{
?//?__dirname是nodejs里的一個(gè)全局變量
?//?它指向的是我們項(xiàng)目的根目錄
?//?入口文件的位置
?entry:?__dirname?+?'/app/main.js
?output:?{
?????//?打包后的文件放置的位置
?????path:?__dirname?+?'/public',
?????//?打包后我們的文件名字
?????filename:?'webpack.js'
?},
?module:?{
?????loaders:?[
?????????{
?????????????test:?/\.josn$/,
?????????????loader:?'json"
?????????},
?????????{
?????????????test:?/\.css$/,
?????????????loader:?"style!css!postcss"?//?右向左執(zhí)行
?????????},
?????????{
?????????????test:?/\.js$/,
?????????????loader:?"babel",
?????????????exclude:?/node_modules/,
?????????????query:?{
?????????????????presets:?['es2015']
?????????????}
?????????}
?????]
?},
?postcss:?[
?????require('autoprefixer')
?],
?plugins:?[
????new?webpack.BannerPlugin('版權(quán)'),?//?在整個(gè)數(shù)組中new一個(gè)就可以了
????//?這里一個(gè)添加版權(quán)聲明的插件是webpack自帶的并不需要安裝插件
????new?Html({
????????template:?__dirname?+?'/app/index.html'
????})
?]
}
webpack之webpack-dev-server
自動(dòng)刷新頁面的功能
webpack開發(fā)服務(wù)器,是webpack官方提供的一個(gè)輔助開發(fā)工具,它可以自動(dòng)監(jiān)控項(xiàng)目下的文件,一旦有修改保存的操作,他就會(huì)主動(dòng)執(zhí)行打包命令,將我們的代碼重新打包,并且需要的話還可以刷新瀏覽器。
npm?install?--save-dev?webpack-dev-server
contentBase 默認(rèn)webpack-dev-server會(huì)為根文件夾提供本地服務(wù)器,如果想為另外一個(gè)目錄下的文件提供本地服務(wù)器,應(yīng)該在這里設(shè)置其所在目錄。
port 設(shè)置默認(rèn)監(jiān)聽端口,如果省略,默認(rèn)為“8080” inline 設(shè)置為true,當(dāng)源文件改變時(shí)會(huì)自動(dòng)刷新頁面 colors 設(shè)置為true,使終端輸出的文件為彩色的 historyApiFallback 在開發(fā)單頁應(yīng)用時(shí)非常有用,它依賴于HTML5 history API,如果設(shè)置為true,所有的跳轉(zhuǎn)將指向index.html
devServer?{
?contentBase:?"./public",?//?本地服務(wù)器所加載的頁面所在的目錄
?colors:?true,?//?終端中輸出結(jié)果為彩色
?historyApiFallback:?true,?//?不跳轉(zhuǎn)
?inline:?true,?//?實(shí)時(shí)刷新
}
webpack.config.js
var?webpack?=?require('webpack');
var?Html?=?require('html-webpack-plugin');
module.exports?=?{
?//?__dirname是nodejs里的一個(gè)全局變量
?//?它指向的是我們項(xiàng)目的根目錄
?//?入口文件的位置
?entry:?__dirname?+?'/app/main.js
?output:?{
?????//?打包后的文件放置的位置
?????path:?__dirname?+?'/public',
?????//?打包后我們的文件名字
?????filename:?'webpack.js'
?},
?module:?{
?????loaders:?[
?????????{
?????????????test:?/\.josn$/,
?????????????loader:?'json"
?????????},
?????????{
?????????????test:?/\.css$/,
?????????????loader:?"style!css!postcss"?//?右向左執(zhí)行
?????????},
?????????{
?????????????test:?/\.js$/,
?????????????loader:?"babel",
?????????????exclude:?/node_modules/,
?????????????query:?{
?????????????????presets:?['es2015']
?????????????}
?????????}
?????]
?},
?postcss:?[
?????require('autoprefixer')
?],
?plugins:?[
????new?webpack.BannerPlugin('版權(quán)'),?//?在整個(gè)數(shù)組中new一個(gè)就可以了
????//?這里一個(gè)添加版權(quán)聲明的插件是webpack自帶的并不需要安裝插件
????new?Html({
????????template:?__dirname?+?'/app/index.html'
????})
?],
?devServer:?{
?????contentBase:?'./public',?//?本地服務(wù)起所加載的頁面所在的目錄
?????colors:?true,
?????inline:?true,?//?實(shí)時(shí)刷新
?????hot:?true
?}
}
webpack-dev-server有兩種啟動(dòng)模式:
iFrame:該模式下修改代碼會(huì)自動(dòng)打包,但不會(huì)刷新瀏覽器
inline:該模式下修改代碼會(huì)自動(dòng)打包,并且會(huì)刷新瀏覽器
運(yùn)行方式:webpack-dev-server --line
模塊熱加載技術(shù),也就是說我們?cè)谛薷拇a后并執(zhí)行保存,代碼不僅可以打包而且會(huì)自動(dòng)刷新我們修改部分的代碼,而不會(huì)刷新瀏覽器。
devServer:?{
????contentBase:?"./public",?//?本地服務(wù)器所加載的頁面所在的目錄
????colors:?true,?//?終端中輸出結(jié)果為彩色
????historyApiFallback:?true,?//?不跳轉(zhuǎn)
????inline:?true,?//?實(shí)時(shí)刷新
????hot:?true?//?允許熱加載
}
webpack-dev-server?--inline?--hot
Fuse.js
Fuse.js 是一個(gè)功能強(qiáng)大、輕量級(jí)的模糊搜索庫,零依賴。
//?1.?List?of?items?to?search?in
const?books?=?[
??{
????title:?"Old?Man's?War",
????author:?{
??????firstName:?'John',
??????lastName:?'Scalzi'
????}
??},
??{
????title:?'The?Lock?Artist',
????author:?{
??????firstName:?'Steve',
??????lastName:?'Hamilton'
????}
??}
]
//?2.?Set?up?the?Fuse?instance
const?fuse?=?new?Fuse(books,?{
??keys:?['title',?'author.firstName']
})
//?3.?Now?search!
fuse.search('jon')
//?Output:
//?[
//???{
//?????item:?{
//???????title:?"Old?Man's?War",
//???????author:?{
//?????????firstName:?'John',
//?????????lastName:?'Scalzi'
//???????}
//?????},
//?????refIndex:?0
//???}
//?
模塊打包工具
模塊打包工具是 為了解決 模塊間的依賴,使其能夠打包后的結(jié)果運(yùn)行在瀏覽器上。
將存在依賴關(guān)系的模塊按照特定規(guī)則合并為單個(gè)JS文件,一次全部加載進(jìn)頁面中。 在頁面初始時(shí)加載一個(gè)入口模塊,其他模塊異步地進(jìn)行加載。
webpack
webpack默認(rèn)支持多種模塊標(biāo)準(zhǔn) webpack有完備的代碼分割解決方案 webpack可以處理各種類型的資源 webpack有龐大的社區(qū)支持
安裝使用本地安裝方式:
如果采用全局安裝,那么在與他人進(jìn)行項(xiàng)目協(xié)作的時(shí)候,由于每個(gè)人系統(tǒng)中的webpack版本不同,可能會(huì)導(dǎo)致結(jié)果不一致。 部分依賴與webpack的插件會(huì)調(diào)用項(xiàng)目中webpack的內(nèi)部模塊,這種情況下仍然需要在項(xiàng)目本地安裝webpack,而如果全局和本地都有,容易造成混淆。
npm?init
//?yarn?init
生成一個(gè)package.json文件,它相當(dāng)于npm項(xiàng)目的說明書,里面記錄了項(xiàng)目名稱,版本,倉庫地址等信息。
npm?install?webpack?webpack-cli?--save-dev
webpack是核心模塊,webpack-cli命令行工具
entry是資源打包的入口 output-filename是輸出資源名 webpack為開發(fā)者提供了development,production,none三種模式
webpack的默認(rèn)配置文件為webpack.config.js:
module.exports?=?{
?entry:?'./src/index.js',
?output:?{
??filename:?'bundle.js',
?},
?mode:?'development',
}
webpack-dev-server
npm?install?webpack-dev-server?--save-dev
npm install --production過濾掉devDependencies中的多余模塊
module.exports?=?{
?entry:?'./src/index.js',
?output:?{
??filename:?'bundle.js',
?},
?mode:?'development',
?devServer:?{
??publicPath:?'/dist',
?},
}
webpack-dev-server是用來接收瀏覽器的請(qǐng)求,然后將資源返回。當(dāng)webpack-dev-server接收到瀏覽器的資源請(qǐng)求時(shí),它會(huì)首先進(jìn)行URL地址校驗(yàn)。如果該地址是資源服務(wù)地址,就會(huì)從webpack的打包結(jié)果中尋找該資源并返回給瀏覽器。反之,如果請(qǐng)求地址不屬于資源服務(wù)地址,則直接讀取硬盤中的源文件并將其返回。
webpack-dev-server:
令webpack進(jìn)行模塊打包,并處理打包結(jié)果的資源請(qǐng)求 作為普通的web server,處理靜態(tài)資源文件請(qǐng)求
webpack可以處理模塊之間的依賴,將它們串聯(lián)起來合并為單一的JS文件,使用本地安裝,可以使團(tuán)隊(duì)開發(fā)時(shí)共用一個(gè)版本,并且可以讓其他插件直接獲取webpack的內(nèi)部模塊。
模塊打包
導(dǎo)出
module.exports?=?{
?name:?'calculater',
?add:?function(a,?b)?{
??return?a?+?b;
?}
};
CommonJS模塊內(nèi)部會(huì)有一個(gè)module對(duì)象用于存放當(dāng)前模塊的信息,可以理解成在每個(gè)模塊的最開始定義的對(duì)象:
var?module?=?{...};
//?模塊自身邏輯
module.exports?=?{...};
應(yīng)用中,??已把module.exports以及exports語句放在模塊的末尾.
在CommonJS中使用require進(jìn)行模塊導(dǎo)入
module.exports?=?{
?add:?func()
}
const?addFun?=?require('./addjs.js');
const?num?=?addFun.add()
require的模塊是第一次被加載,這時(shí)會(huì)首先執(zhí)行該模塊,然后導(dǎo)出內(nèi)容。 require的模塊曾經(jīng)被加載過,該模塊的代碼不會(huì)再次執(zhí)行,而是直接導(dǎo)出上次執(zhí)行后得到的結(jié)果。
模塊中的module對(duì)象用來存放信息,對(duì)象中有個(gè)屬性loaded用于記錄該模塊是否被加載過。默認(rèn)為false,加載過后為true。
動(dòng)態(tài)性
require函數(shù)可以接收表達(dá)式。
const?moduleNames?=?['foo.js',?'bar.js'];
moduleNames.forEach(name?=>?{
?require('./'?+?name);
});
es6模塊
export?default?{
?name:?'dada'
};
import?add?form?'./xx.js';
const?num?=?add.name
ES6 Module會(huì)自動(dòng)采用嚴(yán)格模式
導(dǎo)出
第一種:將變量的聲明和導(dǎo)出寫在一行 第二種:將先進(jìn)行變量聲明,然后再用同一個(gè)export語句導(dǎo)出
在使用命名導(dǎo)出時(shí),可以通過as關(guān)鍵字對(duì)變量重命名。
將export default理解為對(duì)外輸出了一個(gè)名為default的變量,因此不需要像命名導(dǎo)出一樣進(jìn)行變量聲明,直接導(dǎo)出值即可。
//?導(dǎo)出字符串
export?default?'ddd'
導(dǎo)入
在導(dǎo)入多個(gè)變量時(shí),可以采用整體導(dǎo)入的方式
import * as addFunc from 'xxx.js';
兩種導(dǎo)入方式混合:
import?React,?{?Component?}?from?'react';
//?React對(duì)應(yīng)的是該模塊的默認(rèn)導(dǎo)出
//?Component是其命名導(dǎo)出中的一個(gè)變量
復(fù)合寫法
import?calculator?from?'./calculator.js';
export?default?calculator;
CommonJS和ES6 Module
CommonJS和ES6 Module最本質(zhì)的區(qū)別在于前者對(duì)模塊依賴的解決是“動(dòng)態(tài)的”,而后者是“靜態(tài)的”。
動(dòng)態(tài):模塊依賴關(guān)系的建立發(fā)生在代碼運(yùn)行階段;靜態(tài):模塊依賴關(guān)系的建立發(fā)生在代碼編譯階段。
ES6代碼的編譯階段就可以分析出模塊的依賴關(guān)系:
死代碼檢測(cè)和排除,用靜態(tài)分析工具檢測(cè)哪些模塊沒有被調(diào)用過。就是未被調(diào)用到的模塊代碼就是不會(huì)被執(zhí)行的,成了死代碼,通過靜態(tài)分析可以在打包時(shí)去掉這些未曾用過的模塊,來減少打包資源體積。 模塊變量類型檢查,JavaScript屬于動(dòng)態(tài)類型語言,不會(huì)在代碼執(zhí)行前檢查類型錯(cuò)誤。而ES6 Module的靜態(tài)模塊結(jié)構(gòu)有助于確保模塊之間傳遞的值或接口類型是正確的。 編譯器優(yōu)化。CommonJS等動(dòng)態(tài)模塊系統(tǒng)中,無論采用哪種方式,本質(zhì)上導(dǎo)入的都是一個(gè)對(duì)象,而ES6 Module支持直接導(dǎo)入變量,減少了引用層級(jí),程序效率更高。
在導(dǎo)入一個(gè)模塊時(shí),對(duì)于CommonJS來說是一份導(dǎo)出值的拷貝,而ES6 Module則是值的動(dòng)態(tài)映射,并且這個(gè)映射是只讀的。
AMD
AMD是異步模塊定義,與CommonJS和ES6 Module區(qū)別在于它加載模塊的方式是異步的。
通過AMD形式定義模塊的好處在于其模塊加載是非阻塞性的,當(dāng)執(zhí)行到require函數(shù)時(shí)并不會(huì)停下來去執(zhí)行被加載的模塊,而是繼續(xù)執(zhí)行require后面的代碼,
UMD
它的目標(biāo)是使一個(gè)模塊能運(yùn)行在各種環(huán)境下,不論是CommonJS,AMD,還是非模塊化的環(huán)境。
npm
初始化npm工程,通過npm來獲取模塊:
//?項(xiàng)目初始化
npm?init?-y
//?安裝?lodash
npm?install?lodash
//?使用
//?index.js
import?_?from?'lodash';
CommonJS和ES6 Module是目前使用廣泛的,主要區(qū)別前者建立模塊依賴關(guān)系是在運(yùn)行時(shí),后者是編譯時(shí)。在模塊導(dǎo)入方面,CommonJS導(dǎo)入是值拷貝,ES6 Module導(dǎo)入的是只讀的變量映射,ES6 Module通過其靜態(tài)特性可以進(jìn)行編譯過程中的優(yōu)化,并且具備處理循環(huán)依賴的能力。
webpack是一個(gè)在開發(fā)階段進(jìn)行打包的模塊化工具,也就是說它無法不經(jīng)過打包直接在線上使用。webpack同時(shí)兼容AMD、Common.js以及非模塊化的寫法.
使用全局安裝的webpack或者gulp
npm?install?-g?webpack?gulp
可以考慮使用淘寶的鏡像
npm?install?-g?webpack?gulp?--registry=http://registry.npm.taobao.org
入口文件就是在HTML直接引用的,由瀏覽器觸發(fā)執(zhí)行的JS文件。其它的非入口文件則是由入口文件來直接或間接依賴,由JS互相調(diào)用執(zhí)行。
解析文件
(function(modules){
????//?Runtime
})([
????//?模塊數(shù)組
])
Common Chunks 插件的作用就是提取代碼中的公共模塊,然后將公共模塊打包到一個(gè)獨(dú)立的文件中去,以便在其它的入口和模塊中使用。
使用它來提取公共模塊
var?webpack?=?require('webpack');
module.exports?=?{
????entry:{
????????main1:'./main',
????????main2:'./main.2'
????},
????output:{
????????filename:'bundle.[name].js'
????},
????plugins:?[
????????new??webpack.optimize.CommonsChunkPlugin('common.js',?['main1',?'main2'])
????]
};
分割點(diǎn)表示代碼在此處被分割成兩個(gè)獨(dú)立的文件。具體的方式有兩種。
使用require.ensure:
require.ensure(["module-a",?"module-b"],?function(require)?{
????var?a?=?require("module-a");
????//?...
});
使用AMD的動(dòng)態(tài)require:
require(["module-a",?"module-b"],?function(a,?b)?{
????//?...
});
output.publicPath
一般情況下,用上面的配置就能搞定了。但如果你的網(wǎng)站稍大一點(diǎn),可能需要引入CDN,而且很可能CDN還有一些很古怪的前綴,這個(gè)時(shí)候可以通過output.publicPath來搞定。
例如,在前面的例子中,輸出的腳本路徑是dist/example4.1.js,而在生產(chǎn)環(huán)境中訪問的時(shí)候卻有可能是http://cdn.toobug.net/scripts/webpack_guide/dist/example4.1.js。這種情況下,就需要使用output.publicPath來將前面的路徑補(bǔ)全:
output:{
????publicPath:'http://cdn.toobug.net/scripts/webpack_guide/'
}
這樣發(fā)布到生產(chǎn)環(huán)境以后,就會(huì)到CDN上對(duì)應(yīng)的路徑去加載腳本了。
TypeScript(ts-loader)
module:{
????rules:[{
????????test:?/.ts$/,
????????loader:'ts-loader',
????}]
}
bundle-loader是一個(gè)用來在運(yùn)行時(shí)異步加載模塊的loader。
//?在require?bundle時(shí),瀏覽器會(huì)加載它
var?waitForChunk?=?require("bundle!./file.js");
//?等待加載,在回調(diào)中使用
waitForChunk(function(file)?{
????//?這里可以使用file,就像是用下面的代碼require進(jìn)來一樣
????//?var?file?=?require("./file.js");
});
// todo:這句注釋說的是?
//?wraps?the?require?in?a?require.ensure?block
var?load?=?require("bundle?lazy!./file.js");
//?只有在調(diào)用load的時(shí)候才會(huì)真正加載
load(function(file)?{
});
??關(guān)注+點(diǎn)贊+收藏+評(píng)論+轉(zhuǎn)發(fā)??,原創(chuàng)不易,鼓勵(lì)筆者創(chuàng)作更好的文章
點(diǎn)贊、收藏和評(píng)論
我是Jeskson,感謝各位人才的:點(diǎn)贊、收藏和評(píng)論,我們下期見!(如本文內(nèi)容有地方講解有誤,歡迎指出?謝謝,一起學(xué)習(xí)了)
我們下期見!
github收錄,歡迎Star:https://1024bibi.com
