1.安裝webpack
//全局安裝
npm install -g webpack
//安裝到你的項目目錄
npm install --save-dev webpack
這裏記得一定要全局安裝webpack,不然無法在命令行執行webpack指令
2.準備階段
npm init
執行後會在根目錄生成一個package.json的文件
文件目錄結構如下:
// Greeter.js
module.exports = function() {
var greet = document.createElement('div');
greet.textContent = "Hi there and greetings!";
console.log("test");
return greet;
};
//main.js
var greeter = require('./Greeter.js');
document.getElementById('root').appendChild(greeter());
<!--index.html-->
<!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>
//webpack.config.js
module.exports = {
//devtool: 'eval-source-map', //用於調試代碼
entry: __dirname + "/app/main.js", //已多次提及的唯一入口文件
output: {
path: __dirname + "/public", //打包後的文件存放的地方
filename: "bundle.js" //打包後輸出文件的文件名
}
}
3.執行命令打包
當我們在根目錄下有上面寫好完整的webpack.config.js之後,我們可以在命令行執行webpack執行打包,如果成功就會在public文件夾生成一個bundle.js文件
當然你還可以在package.json自己定義好一個執行命令來代替這些繁瑣的命令,例如
//package.json
{
"name": "wscat-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"webpack": "^1.14.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack"
},
"author": "",
"license": "ISC"
}
加上這句之後
"start": "webpack" //配置的地方就是這裏啦,相當於把npm的start命令指向webpack命令
你就可以執行npn run start
還有注意的是,如果不加下面的代碼,在調試代碼的時候很可能就找不到行數了
devtool: 'eval-source-map', //用於調試代碼
加了之後就會顯示未合併之前的文件所在行數
未加則顯示合併後在bundle.js的行數
[外鏈圖片轉存失敗(img-bhfsz9Jg-1567235179965)(https://cloud.githubusercontent.com/assets/17243165/22860444/4a5acdde-f139-11e6-8486-309943a3967c.png)]
devtool選項對應的配置結果
- source-map:在一個單獨的文件中產生一個完整且功能完全的文件。這個文件具有最好的source map,但是它會減慢打包文件的構建速度
- cheap-module-source-map:在一個單獨的文件中生成一個不帶列映射的map,不帶列映射提高項目構建速度,但是也使得瀏覽器開發者工具只能對應到具體的行,不能對應到具體的列(符號),會對調試造成不便
- eval-source-map:使用eval打包源文件模塊,在同一個文件中生成乾淨的完整的source map。這個選項可以在不影響構建速度的前提下生成完整的sourcemap,但是對打包後輸出的JS文件的執行具有性能和安全的隱患。不過在開發階段這是一個非常好的選項,但是在生產階段一定不要用這個選項
- cheap-module-eval-source-map:這是在打包文件時最快的生成source map的方法,生成的Source Map 會和打包後的JavaScript文件同行顯示,沒有列映射,和eval-source-map選項具有相似的缺點
上述選項由上到下打包速度越來越快,不過同時也具有越來越多的負面作用,較快的構建速度的後果就是對打包後的文件的的執行有一定影響
4.配置服務器
npm install -g webpack-dev-server
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: {
contentBase: "./public", //本地服務器所加載的頁面所在的目錄
historyApiFallback: true, //不跳轉
//port 設置默認監聽端口,如果省略,默認爲”8080“
inline: true //實時刷新
}
}
然後在命令行執行webpack-dev-server
[外鏈圖片轉存失敗(img-QK25CxMV-1567235179965)(https://cloud.githubusercontent.com/assets/17243165/22860769/c1ebd39e-f142-11e6-86d7-4b54b578f12a.png)]
在瀏覽器打開http://localhost:8080/
就會顯示靜態頁面,如果改動文件,瀏覽器還會熱更新
devserver配置選項和功能描述
- contentBase:默認webpack-dev-server會爲根文件夾提供本地服務器,如果想爲另外一個目錄下的文件提供本地服務器,應該在這裏設置其所在目錄(本例設置到“public"目錄)
- port:設置默認監聽端口,如果省略,默認爲”8080“
- inline:設置爲true,當源文件改變時會自動刷新頁面
- colors:設置爲true,使終端輸出的文件爲彩色的
- historyApiFallback:在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置爲true,所有的跳轉將指向index.html
5.css-loader
webpack提供兩個工具處理樣式表,css-loader 和 style-loader,二者處理的任務不同
css-loader使你能夠使用類似@import和url(…)的方法實現require()的功能
style-loader將所有的計算後的樣式加入頁面中,二者組合在一起使你能夠把樣式表嵌入webpack打包後的JS文件中
npm install --save-dev style-loader css-loader
然後我們就可以在webpack.config.js文件裏面添加這個loader的配置項
module.exports = {
devtool: 'eval-source-map', //用於調試代碼
entry: __dirname + "/app/main.js", //已多次提及的唯一入口文件
output: {
path: __dirname + "/public", //打包後的文件存放的地方
filename: "bundle.js" //打包後輸出文件的文件名
},
module: {
loaders: [{
test: /\.css$/,
loader: 'style-loader!css-loader'
}, ]
},
devServer: {
contentBase: "./public", //本地服務器所加載的頁面所在的目錄
historyApiFallback: true, //不跳轉
inline: true //實時刷新
}
}
-loader
其實是可以省略不寫的,多個loader之間用“!”連接起來
/*main.css*/
p{
color: red;
}
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Webpack Sample Project</title>
</head>
<body>
<div id='root'>
</div>
<p>hello</p>
<script src="bundle.js"></script>
</body>
</html>
此時我們就可以在main.js裏面直接引進main.css,那所有樣式都會打包成js,在項目運行的時候會轉化爲**
webpack只有單一的入口,其它的模塊需要通過import,require,url等導入相關位置,爲了讓webpack能找到”main.css“文件,我們把它導入”main.js “中
//main.js
var greeter = require('./Greeter.js');
require('./main.css');
document.getElementById('root').appendChild(greeter());
6.url-loader
還可以對圖片進行打包,用這個還要先安裝
module.exports = {
devtool: 'eval-source-map', //用於調試代碼
entry: __dirname + "/app/main.js", //已多次提及的唯一入口文件
output: {
path: __dirname + "/public", //打包後的文件存放的地方
filename: "bundle.js" //打包後輸出文件的文件名
},
module: {
loaders: [{
test: /\.css$/,
loader: 'style-loader!css-loader'
}, {
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=8192'
}]
},
devServer: {
contentBase: "./public", //本地服務器所加載的頁面所在的目錄
historyApiFallback: true, //不跳轉
inline: true //實時刷新
}
}
配置信息的參數“?limit=8192”表示將所有小於8kb的圖片都轉爲base64形式(其實應該說超過8kb的才使用 url-loader 來映射到文件,否則轉爲data url形式)
//main.js
var img1 = document.createElement("img");
img1.src = require("./logo.png");
document.body.appendChild(img1);
7.babel-loader
安裝babel-loader,現在我們就可以放心的用ES6的語法了
npm install --save-dev babel-loader
// Greeter.js
module.exports = function() {
var greet = document.createElement('div');
greet.textContent = "Hi there and greetings!";
console.log("test2");
return greet;
};
可以把上面的代碼用ES6改寫成下面的格式
// Greeter.js
export default function f(){
var greet = document.createElement('div');
greet.textContent = "Hi there and greetings!";
console.log("test2");
return greet;
};
var greeter = require('./Greeter.js'); //ES5
import greeter from './Greeter.js'; //ES6
export與export default均可用於導出常量、函數、文件、模塊等,你可以在其它文件或模塊中通過import+(常量 | 函數 | 文件 | 模塊)名的方式,將其導入,以便能夠對其進行使用,但在一個文件或模塊中,export、import可以有多個,export default僅有一個
所以上面是隻導出一個函數的情況,如果導出多個可以用下面這種方式
// test.js
export const str = 'hello world'
export function f(a){
return a+1
}
import {
str,
f
} from './test.js';
8.vue-loader
vue-loader能夠把我們的組件.vue文件轉化爲js加載到我們項目中
<!-- app.vue-->
<template>
<div>{{msg}}</div>
</template>
<script>
export default {
data() {
return {
msg: 'Hello from vue-loader!'
}
},
}
</script>
<style>
div {
color: red;
}
</style>
這裏面要注意的是vue2開始要用render: (createElement) => createElement(App)
來註冊組件,components在vue1才能使用了,當然在組件.vue文件裏面註冊組件還是可以用components,
還有需要注意的是vue2之後不能在el爲body和html節點上添加組件,所以我這裏改成el: '#app'
var Vue = require('vue')
var App = require('./app.vue')
//import App from './app.vue'
new Vue({
el: '#app',
render: (createElement) => createElement(App)
/*components: {
app: App
}*/
})
webpack.config.js要添加resolve和vue-loader
//webpack.config.js
module.exports = {
devtool: 'eval-source-map', //用於調試代碼
entry: __dirname + "/app/abc.js", //已多次提及的唯一入口文件
output: {
path: __dirname + "/public", //打包後的文件存放的地方
filename: "bundle.js" //打包後輸出文件的文件名
},
module: {
loaders: [{
test: /\.css$/,
loader: 'style-loader!css-loader'
}, {
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=8192'
}, {
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}, {
test: /\.vue$/,
loader: 'vue-loader'
}]
},
devServer: {
contentBase: "./public", //本地服務器所加載的頁面所在的目錄
historyApiFallback: true, //不跳轉
inline: true //實時刷新
},
resolve: {
alias: {
vue: 'vue/dist/vue.js'
}
}
}