開車之前,先介紹一些npm的命令:
:D
進入D盤
mkdir webapp
創建webapp文件夾
cd webapp
進入webapp文件夾
mkdir webapp && cd webapp
以上兩步創建和進入文件夾可以合並為一步
npm init -y
快速生成package.json文件
npm install xxx --save-dev
//安裝模塊並加入到開發依賴中,比如webpack
npm install xxx --save
安裝模塊並加入到生產依賴中,比如Jquery
npm install xxx@2.3.0
下載指定版本
npm view webpack versions --json
如果忘記版本號,可以列出所有版本號
npm install -g cnpm --registry=https://registry.npm.taobao.org
下載淘寶鏡像源,國內npm下載很慢,而且有些包下下來貌似會有問題,比如node-sass。
下載之后就可以直接使用了,使用方式跟Npm一樣,只不過是改成cnpm
cls
清空命令提示符窗口內容
webpack
1. html篇
介紹完npm基本的東西后,下面開始擼webpack
有關webpack的基本概念建議到官網查看,解釋的更為清楚,下面只簡單介紹。
1. 在根目錄下生成package.json文件: npm init -y
2. 安裝webapck cnpm install webpack --save-dev
3. 創建webpack.config.js文件: echo > webpack.config.js
var path=require("path");
module.exports={
<!-- 要打包的文件 -->
entry:"./index.js",
output:{
<!-- 指定打包后的文件名字 -->
filename:"bundle.js",
<!-- 打包后的文件路徑 -->
path:path.resolve(__dirname,"dist")
}
}
4.創建src目錄,並在src目錄下創建index.html, index.js文件並隨便輸一點東西
window.onload=function(){
alert(1)
}
5.執行 webpack 命令,可以發現webpack幫我們在dist下生成了一個main.js文件,打開main.js並拖到最下面你會發現index.js的內容就在里面。
打包完之后,我們在dist生成了js文件,但是我們的index.html在src下面,你可以手動的復制src下的html文件到dist目錄下,並且將打包后的js文件引入。不過像我們這么懶的人,還是希望webpack能夠幫我們在dist下也生成index.html,要是能自動引入打包后的js文件,那就再好不過了。這時候,是時候來一發插件了。
6.cnpm install html-webpack-plugin --save-dev
修改webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require("path")
module.exports = {
entry:"./index.js",
output: {
path: path.resolve(__dirname, 'dist'),
filename:"bundle.js",
},
plugins: [new HtmlWebpackPlugin({
title: "測試"
})]
};
重新執行命令 webpack ,你會發現在dist下多生成了一個index.html文件,打開發現還有一個script的標簽引用着我們打包后的文件,nice。
不過問題又來了,html文件很簡陋,就是emmet幫我們生成的Html5文件,你可能希望還帶有更多的 meta標簽,像這樣的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no, email=no"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
</head>
<body>
<header></header>
<nav></nav>
<div id="app"></div>
<footer></footer>
</body>
此時,你可以自己寫一個模板,只需要告訴html-webpack-plugin插件文件的位置就可以了。
修改webpack.config.js
plugins: [
new htmlWebpackPlugin({
title:"首頁",
<!-- 指定模板位置 -->
template:'./src/index.html',
<!-- 指定打包后的文件名字 -->
filename: 'index.html'
})
]
對於多疑症的你,打包多次后你可能會懷疑文件修改生效了沒有,此時你可以安裝clean-webpack-plugin插件,在每次打包時,先刪除原來的dist目錄,再重新打包,這樣就可以放心的睡覺,不用擔心門沒關了。
7.cnpm install clean-webpack-plugin --save-dev
plugins:[
new htmlWebpackPlugin({
title:"首頁",
template:'./src/index.html',
filename: 'index.html'
}),
<!-- 每次打包前先刪除dist目錄 -->
new CleanWebpackPlugin(['dist'])
]
css篇
以往我們寫css都是寫好后手動通過link引入到html,使用webpack后,你將不再需要手動做這些操作,只需要在js文件中引入,webpack就能幫你搞定,不過需要一些loader和plugin的支持。
cnpm install --save-dev css-loade style-loader
修改webpack.config.js
###為了處理css文件我們需要多配置一個module參數,並使用css-loader來將css文件打包到成“字符串”到js文件中,並使用style-loader將打包后的字符串提取出來並append<style>標簽到head下面
var path=require("path");
var htmlWebpackPlugin=require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports={
entry:{
main:'./src/index.js'
},
output:{
filename:"bundle.js",
path:path.resolve(__dirname,'dist')
},
module:{
rules:[
<!-- test檢測到以xxx結尾的東西use對應的loader -->
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
},
plugins:[
new htmlWebpackPlugin({
title:"首頁",
template:'./src/index.html',
filename:"index.html"
}),
new CleanWebpackPlugin(['dist'])
]
}
哦,聽說你想用sass 預處理 器,那么只需要在use里加多一個sass-loader,並安裝依賴
cnpm install --save-dev sass-loader node-sass
rules:[
{
test: /\.scss$/,
use: [ 'style-loader', 'css-loader',"sass-loader" ]
}
]
什么,想要自動補全瀏覽器后綴autoprefixer?沒問題
cnpm install --save-dev postcss-loader
rules:[
{
test: /\.s?css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader"
},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')({
browsers: ['last 10 versions']
})
]
}
},
{
loader: "sass-loader"
}
]
}
]
這里需要注意,use里面的執行順序是倒序的 ,,webpack會以倒敘的方式處理並將處理后的結果返回給上一個loader,最后通過style-loader將文件的內容append到head下面的style標簽里。
教練,我還想要自動刷新
當你修改一點文件后,你需要重執行命令新編譯文件,然后刷新頁面。如果你使用過gulp的自動刷新比如live-reload,那你也一定希望webpack也有同樣的功能,webpack-dev-server滿足你的需求並且能夠給你更多。
安裝webpack-dev-server到開發依賴 cnpm install --save-dev webpack-dev-server
<!-- 在package.json中加入: -->
"scripts": {
"dev": "webpack-dev-server"
}
通過npm run dev即可執行創建一個服務器,打開localhsot:8080
此時再修改文件,你會發現頁面自動刷新了並且修改生效了,不過你看不到重新編譯后的文件在哪里,應為webpack-dev-server將文件編譯到了內存中 ,比起重新生成文件效率會更高,當然只適用於開發階段。
啟動服務后,如果你 還想讓他自己 打開Localhost,還想 使用模塊熱重載 ,可以加多一個配置
devServer:{
open:true,
hot: true,// 告訴 dev-server我們想用HMR模式
}
開發的時候我們並不在意 style這種形式,但是我們希望在生產環境下 css能從js文件宏分離出來,我們希望能css能跟js並行加載,而且可以避免因為Js文件過大,加載慢而產生的flash of unstyle(無樣式頁面閃爍)。
使用“extract-text-webpack-plugin”插件來分離css代碼。
修改webpack.config.js
cnpm install --save-dev extract-text-webpack-plugin
var path=require("path");
var webpack=require('webpack');
var htmlWebpackPlugin=require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var extractSass = new ExtractTextPlugin({
filename: "[name].[contenthash].css",
disable: process.env.NODE_ENV === "development"
});
//通過設置環境變量來告訴webpack我們在development模式下不需要提取css到單獨在文件,只有當不是development下(也即是production)才需要提取文件。
module.exports={
entry:{
main:'./src/index.js'
},
output:{
filename:"bundle.js",
path:path.resolve(__dirname,'dist')
},
devServer:{
open:true,
hot: true, <!-- 告訴 dev-server我們想用HMR模式 -->
},
module:{
rules:[
{
test: /\.s?css$/,
use: extractSass.extract({
use: [
{
loader: "css-loader"
},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')
]
}
},
{
loader: "sass-loader"
}],
fallback: "style-loader"
})
}
]
},
plugins:[
<!-- 使用此插件來支持熱重載 -->
new webpack.HotModuleReplacementPlugin(),
new htmlWebpackPlugin({
title:"首頁",
template:'./src/index.html',
filename:"index.html"
}),
new CleanWebpackPlugin(['dist']),
extractSass
]
}
修改package.json ,本人為window10系統
"scripts": {
"dev": "set NODE_ENV=development&&webpack-dev-server",
"build":"webpack -p"
}
分別執行npm run dev以及npm run build,你會發先npm run build時css文件被提取到一個單獨的文件了。
##js篇 #####--------------------------------好累啊下面直接上代碼了
為了使用promise,async等es6,7語法,同時兼容低版本瀏覽器,你還需要將js轉碼為es5。
你需要安裝以下依賴包
cnpm install --save-dev
"babel-core": "^6.25.0",
"babel-loader": "^7.0.0",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.5.2",
在module下增加:
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
plugins: ['transform-runtime']
}
}
}
寫一點async或者prmise代碼,打包后發現promise變成了_promise2
##代理
前后端分離開發時經常還會遇到跨域的問題,還可以利用devServer來進行代理
devServer:{
open:true,
hot: true,
proxy: {
'/api/': {
target: 'http://baidu.com',
secure: false,
changeOrigin: true
}
}
$.ajax({
url:'/api/',
success:function(res){
console.log(res)
},
error:function(res){
console.log(res)
}
})
圖片,字體篇
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 8000,
<!-- 小於8k的轉化為Base64 -->
name: '[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 8000,
name: 'font/[name].[hash:7].[ext]'
}
}
你可能想要把所有img或者font文件分別放到一個img或者font文件夾下,可以這么寫:name: 'img/[name].[hash:7].[ext]'
如果你不想下載字體文件下來,可已上傳到阿里字體庫並使用阿里的在線字體圖標,並復制自己的文件的在線地址。
在css里面像這么用:@import url("//at.alicdn.com/t/font_s0zqwb6by3lhm2t9.css");
打包多文件
var path=require("path");
var webpack=require('webpack');
var htmlWebpackPlugin=require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var extractSass = new ExtractTextPlugin({
filename: "[name].[contenthash].css",
disable: process.env.NODE_ENV === "development"
});
module.exports={
entry:{
"main":'./src/js/index.js',
"car":"./src/js/car.js",
"goods":"./src/js/goods.js"
},
output:{
filename:"[name].[hash].js",
path:path.resolve(__dirname,'dist')
},
devServer:{
open:true,
hot: true,
proxy: {
'/api/': {
target: 'http://baidu.com',
secure: false,
changeOrigin: true
}
}
},
module:{
rules:[
{
test: /\.s?css$/,
use: extractSass.extract({
use: [
{
loader: "css-loader"
},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')({
browsers: ['last 10 versions']
})
]
}
},
{
loader: "sass-loader"
}],
fallback: "style-loader"
})
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
plugins: ['transform-runtime']
}
}
},
{
test: /\.html$/,
use: ['html-withimg-loader']
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 8000,
name: 'img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 8000,
name: 'font/[name].[hash:7].[ext]'
}
}
]
},
plugins:[
new webpack.HotModuleReplacementPlugin(),
new htmlWebpackPlugin({
title:"首頁",
template:'./src/index.html',
filename:"index.html",
chunks:["page/main/main"]
}),
new htmlWebpackPlugin({
title:"購物車",
template:'./src/index.html',
filename:"car.html",
chunks:["page/car/car"]
}),
new htmlWebpackPlugin({
title:"商品",
template:'./src/index.html',
filename:"goods.html",
chunks:["page/goods/goods"]
}),
new CleanWebpackPlugin(['dist']),
extractSass,
new webpack.ProvidePlugin({
$:"jquery",
jQuery:"jquery"
})
]
}
上面這樣寫打包后文件都放在一個目錄下,目錄很亂,不方便管理,想讓每個頁面的js,css文件放在對應目錄下,可以按下面這么寫
entry:{
"page/main/main":'./src/js/index.js',
"page/car/car":"./src/js/car.js",
"page/goods/goods":"./src/js/goods.js"
}
如果多個文件都引用了一些其他庫,比如Jquery,vue,你可能想把所有的公共庫提取出來,利用common-chunk插件可以解決。即使你做的是spa單頁面應用,你也可以將公共庫從js文件中提取出來,每次修改時只修改業務邏輯而不重新打包庫,從而可以緩存庫文件。
entry:{
"main/main":'./src/js/index.js',
"car/car":"./src/js/car.js",
"goods/goods":"./src/js/goods.js"
"vendor":["jquery","vue"]
},
plugins:[
new htmlWebpackPlugin({
...同上
chunks:["page/main/main","vendor","mainfest"]
}),
new htmlWebpackPlugin({
...
chunks:["page/car/car","vendor","mainfest"]
}),
new htmlWebpackPlugin({
...
chunks:["page/goods/goods","vendor","mainfest"]
}),
new webpack.optimize.CommonsChunkPlugin({
name:["vendor","mainfest"]
})
]
發現一個問題,在公司電腦dev-server-open自動打開的地址后面會帶undefined,去掉undefined打開網址才正常
https://github.com/linrunzheng/webpackGuide