WebPack能夠看作是模塊打包機:它作的事情是,分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其打包爲合適的格式以供瀏覽器使用。css
構建就是把源代碼轉換成發佈到線上的可執行 JavaScrip、CSS、HTML 代碼,包括以下內容。html
構建實際上是工程化、自動化思想在前端開發中的體現,把一系列流程用代碼去實現,讓代碼自動化地執行這一系列複雜的流程。 構建給前端開發注入了更大的活力,解放了咱們的生產力。前端
mkdir webpack-start cd webpack-start npm init
==> Webpack 啓動後會從Entry
裏配置的Module
開始遞歸解析 Entry 依賴的全部 Module。 每找到一個 Module, 就會根據配置的Loader
去找出對應的轉換規則,對 Module 進行轉換後,再解析出當前 Module 依賴的 Module。 這些模塊會以 Entry 爲單位進行分組,一個 Entry 和其全部依賴的 Module 被分到一個組也就是一個 Chunk
。最後 Webpack 會把全部 Chunk 轉換成文件輸出。 在整個流程中 Webpack 會在恰當的時機執行 Plugin 裏定義的邏輯。node
npm install webpack webpack-cli -D
npm i webpack-dev-server –D
devServer:{ contentBase:path.resolve(__dirname,'dist'), host:'localhost', compress:true, port:8080 }
"scripts": { "build": "webpack --mode development", "dev": "webpack-dev-server --open --mode development " }
經過使用不一樣的Loader,Webpack能夠要把不一樣的文件都轉成JS文件,好比CSS、ES6/七、JSX等react
loader三種寫法jquery
npm i style-loader css-loader -D
配置加載器webpack
module: { rules:[ { test:/\.css$/, use:['style-loader','css-loader'], include:path.join(__dirname,'./src'), exclude:/node_modules/ } ] },
咱們但願自動能產出HTML文件,並在裏面引入產出後的資源web
npm i html-webpack-plugin -D
plugins: [ new HtmlWebpackPlugin({ minify: { removeAttributeQuotes:true }, hash: true, template: './src/index.html', filename:'index.html' })]
npm i file-loader url-loader -D
let logo=require('./images/logo.png'); let img=new Image(); img.src=logo; document.body.appendChild(img);
{ test:/\.(jpg|png|gif|svg)$/, use:'url-loader', include:path.join(__dirname,'./src'), exclude:/node_modules/ }
還能夠在CSS文件中引入圖片正則表達式
.img-bg{ background: url(./images/logo.png); width:173px; height:66px; }
由於CSS的下載和JS能夠並行,當一個HTML文件很大的時候,咱們能夠把CSS單獨提取出來加載npm
npm install --save-dev extract-text-webpack-plugin@next
{ test:/\.css$/, use: ExtractTextWebpackPlugin.extract({ use:'css-loader' }), include:path.join(__dirname,'./src'), exclude:/node_modules/ }, plugins: [ new ExtractTextWebpackPlugin('css/index.css'),
處理圖片路徑問題
const PUBLIC_PATH='/'; output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath:PUBLIC_PATH },
指定打包後的圖片位置
use: [ { loader: 'url-loader', options: { limit: 1024, outputPath:'images/' } } ],
在HTML中使用圖片
npm i html-withimg-loader -D
<div class="img-container "><img src="./images/logo.png" alt="logo.png"></div>
{ test:/\.(html|html)$/, use:'html-withimg-loader', include:path.join(__dirname,'./src'), exclude:/node_modules/ }
npm i less less-loader -D
npm i node-saas sass-loader -D
@color:orange; .less-container{ border:1px solid @color; } $color:green; .sass-container{ border:1px solid $color; }
const cssExtract=new ExtractTextWebpackPlugin('css.css'); const lessExtract=new ExtractTextWebpackPlugin('less.css'); const sassExtract=new ExtractTextWebpackPlugin('sass.css'); { test:/\.less$/, use: lessExtract.extract({ use:['css-loader','less-loader'] }), include:path.join(__dirname,'./src'), exclude:/node_modules/ }, { test:/\.scss$/, use: sassExtract.extract({ use:['css-loader','sass-loader'] }), include:path.join(__dirname,'./src'), exclude:/node_modules/ },
爲了瀏覽器的兼容性,有時候咱們必須加入-webkit,-ms,-o,-moz這些前綴
npm i postcss-loader autoprefixer -D
postcss.config.js
module.exports={ plugins:[require('autoprefixer')] }
.circle {
transform: translateX(100px);
}
{ test:/\.css$/, use: cssExtract.extract({ use:['css-loader','postcss-loader'] }), include:path.join(__dirname,'./src'), exclude:/node_modules/ },
Babel實際上是一個編譯JavaScript的平臺,能夠把ES6/ES7,React的JSX轉義爲ES5
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 babel-preset-react -D
{ test:/\.jsx?$/, use: { loader: 'babel-loader', options: { presets: ["env","stage-0","react"] } }, include:path.join(__dirname,'./src'), exclude:/node_modules/ },
webapck經過配置能夠自動給咱們source maps
文件,map
文件是一種對應編譯文件和源文件的方法
devtool:'eval-source-map'
import _ from 'lodash';
alert(_.join(['a','b','c'],'@'));
new webpack.ProvidePlugin({ _:'lodash' })
當代碼發生修改後能夠自動從新編譯
new webpack.BannerPlugin('珠峯培訓'), watch: true, watchOptions: { ignored: /node_modules/, //忽略不用監聽變動的目錄 aggregateTimeout: 500, //防止重複保存頻繁從新編譯,500毫米內重複保存不打包 poll:1000 //每秒詢問的文件變動的次數 },
有時項目中沒有引用的文件也須要打包到目標目錄
npm i copy-webpack-plugin -D
new CopyWebpackPlugin([{ from: path.join(__dirname,'public'),//靜態資源目錄源地址 to:'./public' //目標地址,相對於output的path目錄 }]),
npm i clean-webpack-plugin -D
new cleanWebpaclPlugin(path.join(__dirname,'dist'))
壓縮JS可讓輸出的JS文件體積更小、加載更快、流量更省,還有混淆代碼的加密功能
npm i uglifyjs-webpack-plugin -D
plugins: [ new UglifyjsWebpackPlugin(), ]
webpack能夠消除未使用的CSS,好比bootstrap中那些未使用的樣式
npm i -D purifycss-webpack purify-css
npm i bootstrap -S
{ test:/\.css$/, use: cssExtract.extract({ use: [{ loader: 'css-loader', options:{minimize:true} },'postcss-loader'] }), },
new PurifyCSSPlugin({ //purifycss根據這個路徑配置遍歷你的HTML文件,查找你使用的CSS paths:glob.sync(path.join(__dirname,'src/*.html')) }),
若是你有單獨的後端開發服務器 API,而且但願在同域名下發送 API 請求 ,那麼代理某些 URL 會頗有用。
//請求到 /api/users 如今會被代理到請求 http://localhost:9000/api/users。 proxy: { "/api": "http://localhost:9000", }
proxy: { "/api": { target: "http://localhost:9000", pathRewrite: {"^/api":""} } }
指定extension以後能夠不用在require或是import的時候加文件擴展名,會依次嘗試添加擴展名進行匹配
resolve: { //自動補全後綴,注意第一個必須是空字符串,後綴必定以點開頭 extensions: ["",".js",".css",".json"], },
配置別名能夠加快webpack查找模塊的速度
const bootstrap=path.join(__dirname,'node_modules/bootstrap/dist/css/bootstrap.css') resolve: { alias: { 'bootstrap': bootstrap } },
許多 library 將經過與 process.env.NODE_ENV 環境變量關聯,以決定 library 中應該引用哪些內容。例如,當不處於生產環境中時,某些 library 爲了使調試變得容易,可能會添加額外的日誌記錄(log)和測試(test)。其實,當使用 process.env.NODE_ENV === 'production' 時,一些 library 可能針對具體用戶的環境進行代碼優化,從而刪除或添加一些重要代碼。咱們能夠使用 webpack 內置的 DefinePlugin 爲全部的依賴定義這個變量:
npm install cross-env -D
"scripts": { "build": "cross-env NODE_ENV=production webpack --mode development", "dev": "webpack-dev-server --open --mode development " },
plugins: [ new webpack.DefinePlugin({ NODE_ENV:JSON.stringify(process.env.NODE_ENV) }),
if (process.env.NODE_ENV == 'development') { console.log('這是開發環境'); } else { console.log('這是生產環境'); }
require("expose-loader?libraryName!./file.js"); require("expose-loader?_!loadash"); let _=require('expose-loader?_!lodash');
{ test: /^lodash$/, loader: "expose?_" }
setTimeout(function(){ console.log(window._); });
有時候咱們的頁面能夠不止一個HTML頁面,會有多個頁面,因此就須要多入口
entry: { index: './src/index.js', main:'./src/main.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[hash].js', publicPath:PUBLIC_PATH }, new HtmlWebpackPlugin({ minify: { removeAttributeQuotes:true }, hash: true, template: './src/index.html', chunks:['index'], filename:'index.html' }), new HtmlWebpackPlugin({ minify: { removeAttributeQuotes:true }, hash: true, chunks:['main'], template: './src/main.html', filename:'main.html' })],
若是咱們想引用一個庫,可是又不想讓webpack打包,而且又不影響咱們在程序中以CMD、AMD或者window/global全局等方式進行使用,那就能夠經過配置externals
const $ = require("jquery");
const $ = window.jQuery;
externals: { jquery: "jQuery"//若是要在瀏覽器中運行,那麼不用添加什麼前綴,默認設置就是global },