模塊打包工具,分析項目結構,找到js模塊及一些瀏覽器不能運行的語言如ES6/sass等,並將其轉換和打包爲什麼時的格式供瀏覽器使用;css
- 打包:將多個js文件打包成一個文件,減小服務器壓力和下載帶寬;
- 轉換:把瀏覽器不能識別的語言轉換爲js,讓瀏覽器可以正確識別
- 優化:優化項目,提升性能
// 新建項目文件夾,並進入 mkdir webpack_demo cd webpack_demo //全局安裝 npm install -g webpack // 全局安裝後還需進行一個項目目錄的安裝,npm安裝以前先進行初始化,目的-生成package.json文件(包括當前項目依賴模塊,自定義腳本任務等) npm n init // 項目目錄的安裝 --save-dev保存到package.json中且在dev開發中使用,生產環境中不使用; npm install --save-dev webpack // 查看webpack版本 webpack -v // ps:查看webpack版本時會提示安裝webpack-cli,由於此時安裝的webpack版本是4.x;webpack 已經將 webpack 命令行相關的內容都遷移到 webpack-cli,因此除了 webpack 外,還須要安裝 webpack-cli npm install --save-dev webpack-cli -g
創建基本項目結構,根目錄下創建src和dist文件夾html
- src:存放JavaScript代碼
- dist:用來存放瀏覽器讀取的文件,webpack打包後的文件
- 手動在dist文件夾下新建index.html,並寫入代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>jspang webpack</title> </head> <body> <div id="title"></div> <script src="./bundle.js"></script> </body> </html>
- 此處引入的bundle.js文件目前尚未,後續webpack打包生成該文件;
- 在src下創建入口文件entry.js:
document.getElementById('title').innerHTML='Hello Webpack';
- webpack打包,webpack3.x打包方式webpack src/entry.js ./dist/bundle.js,但webpack4.x已不支持該打包方式,
// 報錯信息 The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
- 解決辦法,在package.json中增長scripts命令:
"dev": "webpack --mode development", "build": "webpack --mode production"
- npm run build 則在dist文件夾下建立一個打包好的main.js文件,若輸出文件名須要更改,如輸出bundle.js,則能夠在根目錄下新建webpack.config.js文件,設置輸入輸出文件狀況
const path = require('path') module.exports = { entry:'./src/entry.js', output:{ path:path.resolve(__dirname, 'dist'), filename:'bundle.js' }, mode:'development' }
- 運行npm run build並在瀏覽器裏打開index.html便可看到Hello Webpack
webpack.config.js是Webpack的配置文件,該文件須要本身在項目根目錄下手動創建而後對其進行配置,配置模板以下:
~~~
module.exports={
// 入口文件的配置項
entry:{},
// 出口文件的配置項
output:{},
// 模塊:例如解讀CSS,圖片如何轉換,壓縮
module:{},
// 插件,用於生產模版和各項功能
plugins:[],
// 配置webpack開發服務功能
devServer:{}
}
~~~node
// 入口文件的配置項 entry:{ //裏面的entery是能夠隨便寫的 entry:'./src/entry.js' }
// 出口配置是用來告訴webpack最後打包文件的地址和文件名稱的 output:{ //打包的路徑位置,path.resolve(__dirname,’dist’)獲取項目的絕對路徑 path:path.resolve(__dirname,'dist'), //打包的文件名稱 filename:'bundle.js' }
ps:記得引入path,不然找不到path,沒法使用resolve方法react
const path = `require`('path');
多入口-多出口配置webpack
const path = `require`('path'); module.exports={ // 入口文件的配置項 entry:{ entry:'./src/entry.js', // 又引入了一個入口文件 entry2:'./src/entry2.js' }, // 出口文件的配置項 output:{ // 輸出的路徑,用了Node語法 path:path.resolve(__dirname,'dist'), // 輸出的文件名稱 // [name]的意思是根據入口文件的名稱,打包成相同的名稱,有幾個入口文件,就能夠打包出幾個文件 filename:'[name].js' }, // 模塊:例如解讀CSS,圖片如何轉換,壓縮 module:{}, // 插件,用於生產模版和各項功能 plugins:[], // 配置webpack開發服務功能 devServer:{} }
要執行webpack-dev-server要先npm install webpack-dev-server –save-dev,而後配置一下devServercss3
// webpack.config.js devServer:{ //設置基本目錄結構 contentBase:path.resolve(__dirname,'dist'), //服務器的IP地址,可使用IP也可使用localhost host:'localhost', //服務端壓縮是否開啓 compress:true, //配置服務端口號 port:1717 }
- contentBase:配置服務器基本運行路徑,用於找到程序打包地址;
- host:服務運行地址,建議使用本機IP;
- compress:服務器端壓縮選型,通常設置爲開啓;
- port:服務運行端口;
// --save-dev 本地安裝並保存到package.json npm install webpack-dev-server --save-dev
// package.json "devDependencies": { "webpack-dev-server": "^3.8.0" }
而後在package.json的文件夾中增長scripts命令:web
"scripts": { "server":"webpack-dev-server" }
運行npm run server , 成功以後在瀏覽器中打開http://localhost:1717/ 便可看到index.html中對應內容npm
在npm run server 啓動後,它是有一種監控機制的(也叫watch)。它能夠監控到咱們修改源碼,並當即在瀏覽器裏給咱們更新。json
webpack 的 webapck-dev-server 包會啓動一個開發服務器,當修改入口文件或者入口文件中引入的其餘文件時,webpack會自動編譯入口文件,而後刷新整個頁面。ps:改變html或樣式不會自動刷新頁面,須要手動刷新才能看到效果。windowswindows
解決html改變不刷新的問題:使用插件 npm install --save-dev html-webpack-plugin
// webpack.config.js var HtmlWebpackPlugin = require('html-webpack-plugin'); plugins:[ new HtmlWebpackPlugin({template: './dist/index.html'}) ],
經過使用不一樣的Loader,Webpack能夠對不一樣的文件格式進行特定處理
Loaders的配置:
- test:用於匹配處理文件的擴展名的表達式;
- use:loader名稱,即要使用模塊的名稱;
- include/exclude:手動添加必須處理的文件(文件夾)或屏蔽不須要處理的文件(文件夾)(可選);
- query:爲loaders提供額外的設置選項(可選);
在/src下,創建一個css文件夾,並創建index.css文件
#title{ font-size: 20px; color:red; } body{ background-color:gainsboro; }
CSS文件創建好後,須要引入到入口文件中,才能夠打包到,這裏引入到entry.js中。/src/entery.js中在首行加入代碼:
import css from './css/index.css';
使用loader解析CSS文件,style-loader(用來處理css文件中的url()等)和css-loader(將css插入到頁面的style標籤) npm install style-loader --save-dev npm install --save-dev css-loader
module:{ rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] } ] },
module:{ rules:[ { test:/\.css$/, loader:['style-loader','css-loader'] } ] },
module:{ rules:[ { test:/\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader" } ] } ] },
ps:此時更改css能夠自動刷新;以上三種寫法均可以
uglifyjs-webpack-plugin(JS壓縮插件,簡稱uglify webpack裏已集成,不需再次安裝。
const uglify = `require`('uglifyjs-webpack-plugin'); plugins:[ new uglify() ],
ps:devServer和JS壓縮的衝突 致使此時運行出錯
開發環境中是基本不會對js進行壓縮的,在開發預覽時咱們須要明確的報錯行數和錯誤信息,因此徹底沒有必要壓縮JavasScript代碼。而生產環境中才會壓縮JS代碼,用於加快程序的工做效率。devServer用於開發環境,而壓縮JS用於生產環境,在開發環境中做生產環境的事情因此Webpack設置了衝突報錯。
將dist文件下html文件剪切到src目錄中,並去掉js的引入,webpack會自動引
webpack.config.js 引入html-webpack-plugin插件並安裝 npm install --save-dev html-webpack-plugin
const htmlPlugin= require('html-webpack-plugin');
在webpack.config.js裏的plugins裏進行插件配置
new htmlPlugin({ minify:{ removeAttributeQuotes:true }, hash:true, template:'./src/index.html' })
- minify:是對html文件進行壓縮,removeAttrubuteQuotes是去掉屬性的雙引號。
- hash:爲了開發中js有緩存效果,因此加入hash,這樣能夠有效避免緩存JS。
- template:是要打包的html模版路徑和文件名稱。
在終端中使用webpack,進行打包。可看到index.html文件已經被打包到咱們的dist目錄下了,且自動引入了入口的JS文件
html文件的打包能夠有效的區分開發目錄和生產目錄,在webpack的配置中要清楚哪些配置用於生產環境,哪些配置用於開發環境,避免兩種環境的配置衝突
src目錄下新建imgs文件夾,在src下的index.html文件中引入該圖片,運行報錯,缺乏loader的解析,安裝file-loader和url-loader
npm install --save-dev file-loader url-loader
- file-loader:解決引用路徑問題,css中引入背景圖,webpack將把各個模塊打包成一個文件,樣式中的url是相對入口html的而不是相對原始css文件所在的路徑的,則會致使圖片引入失敗;可使用file-loader解決,file-loader能夠解析項目中的url引入,根據配置能夠將圖片拷貝到相應的路徑,修改打包後的文件引用路徑,使之指向正確的文件
- url-loader:不少圖片會發送不少http請求,下降頁面性能,可使用url-loader解決。url-loader會將引入的圖片編碼,生成dataURI,至關於把數據翻譯成一串字符(base64),再把字符打包到文件中,因此只須要引入這個文件就能訪問圖片了。若是圖片較大,編碼會消耗性能,所以url-loader提供了一個limit參數,小於該字節的文件被轉爲dataURI,大於的使用file-loader進行copy
- url-loader封裝了file-loader,因此只需引入url-loader便可
//模塊:例如解讀CSS,圖片如何轉換,壓縮 module:{ rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },{ test:/\.(png|jpg|gif)/ , use:[{ loader:'url-loader', options:{ limit:500000 } }] } ] },
- test:/.(png|jpg|gif)/是匹配圖片文件後綴名稱。
- use:是指定使用的loader和loader的配置參數。
- limit:是把小於500000B的文件打成Base64的格式,寫入JS。
- 1.文件大小小於limit參數,url-loader將會把文件轉爲DataURL(Base64格式);
- 2.文件大小大於limit,url-loader會調用file-loader進行處理,參數也會直接傳給file-loader
- 把CSS從JavasScript代碼中分離出來,
- 如何處理分離出來後CSS中的圖片路徑不對問題。
CSS分離:extract-text-webpack-plugin npm install --save-dev extract-text-webpack-plugin
const extractTextPlugin = require("extract-text-webpack-plugin"); // 設置plugins new extractTextPlugin("/css/index.css") // 這裏的/css/index.css是分離後的路徑位置。這部配置完成後,包裝代碼:還要修改原來咱們的style-loader和css-loader。 module:{ rules: [ { test: /\.css$/, use: extractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) },{ test:/\.(png|jpg|gif)/ , use:[{ loader:'url-loader', options:{ limit:500000 } }] } ] },
圖片路徑問題:
publicPath:是在webpack.config.js文件的output選項中,主要做用就是處理靜態文件路徑的。
在處理前,咱們在webpack.config.js 上方聲明一個對象,叫website
var website ={ publicPath:"http://本機或devServer配置的ip:1717/" }
而後在output選項中引用這個對象的publicPath屬性。
//出口文件的配置項 output:{ //輸出的路徑,用了Node語法 path:path.resolve(__dirname,'dist'), //輸出的文件名稱 filename:'[name].js', publicPath:website.publicPath },
html-withimg-loader能夠很好的處理咱們在html中引入圖片的問題
"scripts": { "server": "webpack-dev-server --open", "build":"webpack" },
則能夠直接使用npm run build 即至關於全局使用webpack命令,完成打包;
如何把圖片放到指定的文件夾下:配置url-loader選項
module:{ rules: [ { test: /\.css$/, use: extractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) },{ test:/\.(png|jpg|gif)/ , use:[{ loader:'url-loader', options:{ limit:5000, outputPath:'imgs/', } }] } ] },
outputPath:'imgs/',若是圖片大小小於limit值,則圖片會生成base64格式,則dist文件夾下就不會生成imgs標籤,而若是圖片大於limit值,則不會採用生成字符串形式處理圖片,而是採用file-loader方式copy圖片,則此時會生成imgs文件夾並調整圖片引用路徑;
ps:在不設置limit時,limit自帶默認值
html-withimg-loader 解決在hmtl文件中引入標籤的問題 npm install html-withimg-loader --save
{ test: /\.(htm|html)$/i, use:[ 'html-withimg-loader'] }
npm install --save-dev less npm n install --save-dev less-loader
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: /\.less$/, use: extractTextPlugin.extract({ use: [{ loader: "css-loader" }, { loader: "less-loader" }], // use style-loader in development fallback: "style-loader" }) }
npm n install --save-dev node-sass npm install --save-dev sass-loader
{ test: /\.scss$/, use: [{ loader: "style-loader" // creates style nodes from JS strings }, { loader: "css-loader" // translates CSS into CommonJS }, { loader: "sass-loader" // compiles Sass to CSS }] }
// 把SASS文件分離 { test: /\.scss$/, use: extractTextPlugin.extract({ use: [{ loader: "css-loader" }, { loader: "sass-loader" }], // use style-loader in development fallback: "style-loader" }) }
不要忘記把sass文件引入到entery.js中。
// 屬性前綴 -webkit-transform: rotate(45deg); transform: rotate(45deg);
瀏覽器的兼容性,加入-webkit,-ms,-o,-moz這些前綴。PostCSS是一個CSS的處理平臺,它能夠幫助你的CSS實現更多的功能,如加前綴的功能
須要安裝兩個包postcss-loader 和autoprefixer(自動添加前綴的插件)
npm install --save-dev postcss-loader autoprefixer
postCSS推薦在項目根目錄(和webpack.config.js同級),創建一個postcss.config.js文件
module.exports = { plugins: [ require('autoprefixer') ] }
{ test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader", options: { modules: true } }, { loader: "postcss-loader" } ] }
{ test: /\.css$/, use: extractTextPlugin.extract({ fallback: 'style-loader', use: [ { loader: 'css-loader', options: { importLoaders: 1 } }, 'postcss-loader' ] }) }
使用PurifyCSS能夠大大減小CSS冗餘 npmn i -D purifycss-webpack purify-css
須要同步檢查html模板,則需引入node的glob對象使用。在webpack.config.js文件頭部引入glob purifycss-webpack
const glob = require('glob');
const PurifyCSSPlugin = require("purifycss-webpack");
plugins:[ //new uglify() new htmlPlugin({ minify:{ removeAttrubuteQuotes:true }, hash:true, template:'./src/index.html' }), new extractTextPlugin("css/index.css"), new PurifyCSSPlugin({ // Give paths to parse for rules. These should be absolute! paths: glob.sync(path.join(__dirname, 'src/*.html')), }) ]
paths,主要是需找html模板,purifycss根據這個配置會遍歷你的文件,查找哪些css被使用了。
Babel是幾個模塊化的包,其核心功能位於稱爲babel-core的npm包中,webpack能夠把其不一樣的包整合在一塊兒使用,對於每個你須要的功能或拓展,你都須要安裝單獨的包(用得最多的是解析ES6的babel-preset-es2015包和解析JSX的babel-preset-react包)。
cnpm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
{ test:/\.(jsx|js)$/, use:{ loader:'babel-loader', options:{ presets:[ "es2015","react" ] } }, exclude:/node_modules/ }
如今官方推薦使用的是babel-preset-env, npm n install --save-dev babel-preset-env
而後修改.babelrc裏的配置文件。其實只要把以前的es2015換成env就能夠了。
{ "presets":["react","env"] }
ps:extract-text-webpack-plugin不知是版本問題仍是什麼狀況,不正常啊
參考 & 感謝:
https://jspang.com/posts/2017/09/16/webpack3.html(強烈推薦啊)
https://www.jianshu.com/p/c094e42b0bc2
http://www.javashuo.com/article/p-dymyrwzw-co.html