安裝
作為項(xiàng)目依賴安裝
npm install --save-dev webpack@3.5.5
最新版本bug太多,這里我們指定3.5.5版本
window下若出現(xiàn)問題(Cannot find module 'webpack/lib/node/NodeTemplatePlugin”),則在命令行窗口輸入
npm config get prefix
,會(huì)得到輸出路徑捕虽,添加至環(huán)境變量即可
鍵:NODE-PATH 值:F:\Program Files\nodejs\node_modules
總覽
官網(wǎng)對(duì)webpack的定義是MODULE BUNDLER晦鞋,他的目的就是把有依賴關(guān)系的各種文件打包成一系列的靜態(tài)資源。 請(qǐng)看下圖
webpack簡(jiǎn)單點(diǎn)來說就就是一個(gè)配置文件,所有的魔力都是在這一個(gè)文件中發(fā)生的艺配。 這個(gè)配置文件主要分為三大塊
- entry 入口文件 讓webpack用哪個(gè)文件作為項(xiàng)目的入口
- output 出口 讓webpack把處理完成的文件放在哪里
- module 模塊 要用什么不同的模塊來處理各種類型的文件
下面我們就一步一步來新建一個(gè)簡(jiǎn)單的項(xiàng)目
建立項(xiàng)目
建一個(gè)文件夾钢猛,然后新建一個(gè)package.json的文件在項(xiàng)目根目錄下
mkdir webpack
cd webpack
npm init
# 一直點(diǎn)回車 如果懶得填一些信息
項(xiàng)目結(jié)構(gòu)
/app
- index.js
- sub.js
package.json
webpack.config.js
添加了兩個(gè)js文件伙菜,添加了最重要的webpack的配置文件,我們還是從非常簡(jiǎn)單的hello world開始玩起命迈,webpack原生直接支持AMD和CommonJS兩種格式贩绕,如果你想使用ES6的風(fēng)格火的,這點(diǎn)以后再提。
JS代碼
sub.js
//我們這里使用CommonJS的風(fēng)格
function generateText() {
var element = document.createElement('h2');
element.innerHTML = "Hello h2 world";
return element;
}
module.exports = generateText;
index.js
var sub = require('./sub');
var app = document.createElement('div');
app.innerHTML = '<h1>Hello World</h1>';
app.appendChild(sub());
document.body.appendChild(app);
代碼寫完了淑倾,完成一個(gè)很簡(jiǎn)單的功能馏鹤,新建一個(gè)單獨(dú)的module,并且在另外一個(gè)module里面引用他娇哆,最后會(huì)在頁面里面輸出兩個(gè)標(biāo)題湃累。
配置Webpack
現(xiàn)在開始配置webpack,目標(biāo)是把這兩個(gè)js文件合并成一個(gè)文件. 我們可以自己在build文件夾里面手動(dòng)建一個(gè)index.html文件夾迂尝,然后再把合并以后的js引用在里面脱茉,但是這樣有些麻煩,所以我們這里安裝一個(gè)plugin垄开,可以自動(dòng)快速的幫我們生成HTML琴许。
npm install html-webpack-plugin --save-dev
好 有了這個(gè)插件 開始寫config文件
var path = require('path');
var HtmlwebpackPlugin = require('html-webpack-plugin');
//定義了一些文件夾的路徑
var ROOT_PATH = path.resolve(__dirname);
var APP_PATH = path.resolve(ROOT_PATH, 'app');
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');
module.exports = {
//項(xiàng)目的文件夾 可以直接用文件夾名稱 默認(rèn)會(huì)找index.js 也可以確定是哪個(gè)文件名字
entry: APP_PATH,
//輸出的文件名 合并以后的js會(huì)命名為bundle.js
output: {
path: BUILD_PATH,
filename: 'bundle.js'
},
//添加我們的插件 會(huì)自動(dòng)生成一個(gè)html文件
plugins: [
new HtmlwebpackPlugin({
title: 'Hello World app'
})
]
};
然后配置package.json
"scripts": {
"build": "webpack"
}
項(xiàng)目根目錄執(zhí)行
npm run build
終端顯示一堆信息,然后告訴你成功了溉躲。
你可以使用webpack --help看看一些運(yùn)行的時(shí)候可選的參數(shù)
你會(huì)發(fā)現(xiàn)多出來一個(gè)build文件夾榜田,直接點(diǎn)開里面的html文件,你會(huì)發(fā)現(xiàn)我們可愛的“hello world”已經(jīng)插入到頁面了锻梳。我們的任務(wù)完成了箭券,成功生成html,合并js疑枯,html引入了js辩块,js被執(zhí)行了。
配置webpack-dev-server
上面任務(wù)雖然完成了荆永,但是我們要不斷運(yùn)行程序然后查看頁面废亭,所以最好新建一個(gè)開發(fā)服務(wù)器,可以serve我們pack以后的代碼具钥,并且當(dāng)代碼更新的時(shí)候自動(dòng)刷新瀏覽器豆村。
安裝webpack-dev-server
npm install webpack-dev-server@2.7.1 --save-dev
安裝完畢后 在config中添加配置
module.exports = {
....
devServer: {
historyApiFallback: true,
hot: true,
inline: true,
contentBase: "./app"
},
...
}
然后再package.json里面配置一下運(yùn)行的命令,npm支持自定義一些命令
...
"scripts": {
"start": "webpack-dev-server --hot --inline"
},
...
好了,萬事具備了骂删,在項(xiàng)目根目錄下輸入npm start,一堆花花綠綠的信息后server已經(jīng)起來了掌动,在瀏覽器里面輸入[http://localhost:8080 ] 發(fā)現(xiàn)偉大的hello world出現(xiàn)了,在js里面隨便修改一些輸出然后保存, boom!瀏覽器自動(dòng)刷新宁玫,新的結(jié)果出現(xiàn)了粗恢。
添加CSS樣式
現(xiàn)在來添加一些樣式,webpack使用loader的方式來處理各種各樣的資源欧瘪,比如說樣式文件适滓,我們需要兩種loader,css-loader 和 style-loader,css-loader會(huì)遍歷css文件凭迹,找到所有的url(...)并且處理。style-loader會(huì)把所有的樣式插入到你頁面的一個(gè)style tag中苦囱。
安裝我們的loader
npm install css-loader style-loader --save-dev
配置loader嗅绸,在webpack.config.js中
devServer: {
historyApiFallback: true,
hot: true,
inline: true,
progress: true,
},
...
module: {
loaders: [
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader']
}
]
},
...
plugins: [
new HtmlwebpackPlugin({
title: 'Hello World app'
})
]
看loaders的書寫方式,test里面包含一個(gè)正則撕彤,包含需要匹配的文件鱼鸠,loaders是一個(gè)數(shù)組,包含要處理這些程序的loaders羹铅,這里我們用了css和style蚀狰,注意loaders的處理順序是從右到左的,這里就是先運(yùn)行css-loader然后是style-loader.
新建一個(gè)樣式文件 main.css
h1 {
color: red;
}
記得在入口文件index.js中引用
require('./main.css');
然后發(fā)現(xiàn)標(biāo)題變成紅色的了职员,webpack的理念是基于項(xiàng)目處理的麻蹋,把對(duì)應(yīng)的文件格式給對(duì)應(yīng)的loader處理,然后你就不用管了焊切,它會(huì)決定怎么壓縮扮授,編譯。
那現(xiàn)在想使用一些有愛的css預(yù)編譯程序专肪,來點(diǎn)sass吧刹勃。 你可能已經(jīng)想到了,再來個(gè)loader就行啦嚎尤,確實(shí)是這樣簡(jiǎn)單荔仁。
npm install sass-loader node-sass --save-dev
稍微修改一下config,刪掉我們先前添加的css規(guī)則芽死,加上下面的loader
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
},
添加兩個(gè)sass文件乏梁,variables.scss和main.scss
variables.scss
$red:red;
main.css
@import "./variables.scss";
h1 {
color: $red;
}
在index.js中引用
require('./main.scss');
然后發(fā)現(xiàn)標(biāo)題如愿變紅
處理圖片和其他靜態(tài)文件
這個(gè)和其他一樣,也許你也已經(jīng)會(huì)玩了收奔。安裝loader掌呜,處理文件。諸如圖片坪哄,字體等等质蕉,不過有個(gè)神奇的地方它可以根據(jù)你的需求將一些圖片自動(dòng)轉(zhuǎn)成base64編碼的,為你減輕很多的網(wǎng)絡(luò)請(qǐng)求翩肌。
安裝url-loader
npm install url-loader --save-dev
配置config文件
{
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=40000'
}
注意后面那個(gè)limit的參數(shù)模暗,當(dāng)你圖片大小小于這個(gè)限制的時(shí)候,會(huì)自動(dòng)啟用base64編碼圖片念祭。
添加第三方庫
有的時(shí)候還想來點(diǎn)jquery兑宇,moment,undersocre之類的庫粱坤,webpack可以非常容易的做到這一點(diǎn)隶糕,有謠言說Bower即將停止開發(fā)了, 作者推薦都使用npm來管理依賴瓷产。那么我們現(xiàn)在安裝在我們的app中添加jquery和moment的支持。
npm install jquery moment --save-dev
在js中引用
var sub = require('./sub');
var $ = require('jquery');
var moment = require('moment');
var app = document.createElement('div');
app.innerHTML = '<h1>Hello World it</h1>';
document.body.appendChild(app);
app.appendChild(sub());
$('body').append('<p>look at me! now is ' + moment().format() + '</p>');
添加ES6的支持
首先 裝各種loader
npm install babel-loader babel-preset-env --save-dev
配置我們的config文件
...
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
}
...
為了配合開發(fā)環(huán)境需下載
npm install babel-plugin-transform-object-rest-spread --save-dev
最終如下
{
test: /\.js$/,
use:{
loader:"babel-loader",
options:{
presets:["env"],
plugins: [require('babel-plugin-transform-object-rest-spread')]
}
}
}
現(xiàn)在我們可以改掉CommonJS風(fēng)格的文件了枚驻。
sub.js
export default function() {
var element = document.createElement('h2');
element.innerHTML = "Hello h2 world hahaha";
return element;
}
index.js
import './main.scss';
import generateText from './sub';
import $ from 'jquery';
import moment from 'moment';
let app = document.createElement('div');
const myPromise = Promise.resolve(42);
myPromise.then((number) => {
$('body').append('<p>promise result is ' + number + ' now is ' + moment().format() + '</p>');
});
app.innerHTML = '<h1>Hello World it</h1>';
document.body.appendChild(app);
app.appendChild(generateText());
我們上面測(cè)試了import, export濒旦,const,let再登,promise等一系列es6的特性尔邓。
最后完美的輸出界面。歡迎光臨個(gè)人站清風(fēng)筆記