以前一直據說 webpack 的大名,惋惜不曾得見。今天有空,初步瞭解了 Webpack 工做方式後,一步步的開始學習使用 Webpack,並把其中的關鍵點記錄下來css
這不是一個教程,是工做當中用到的時候才寫的,全部看起來會有點亂
npm init
npm install --save-dev webpack webpack-clihtml
let path = require('path'); let webpack = require('webpack'); module.exports = { mode: "development", // 模式配置 development || production entry: '', // 入口文件 output: {}, // 出口文件 module: {}, // 處理對應模塊 plugins: [], // 對應的插件 devServer: {}, // development 下開發服務器 }
若是文件被更新,代碼將被從新編譯node
npm install --save-dev webpack-dev-server // webpack.config.js devServer: { contentBase: './dist', // 靜態文件根目錄 hot: true, // 模塊熱替換 overlay: true, // 瀏覽器頁面上顯示錯誤 stats: "errors-only", // 控制編譯的時候shell上的輸出內容 minimal || normal || verbose compress: true // 服務器返回瀏覽器的時候是否啓動gzip壓縮 }, module.exports = { plugins: [ new webpack.NamedModulesPlugin(), // 熱替換,熱替換不是刷新 new webpack.HotModuleReplacementPlugin() ], } //package.json "start": "webpack-dev-server --open",
js中的內容修改保存後,在不刷新頁面的狀況下直接修改掉,這樣就實現了熱更新react
開發中方便的調試能極大的提升開發效率,不過經過打包後的文件,很難找到出錯了的地方,Source Maps 就是來幫咱們解決這個問題的webpack
// webpack.config.js devtool: 'inline-source-map' // 有多種選項
使用hash值以後,每次打包的文件都不同,dist裏面的文件會愈來愈多,須要每次打包前清空文件夾
文件都打包好了,可是咱們在使用的時候不能在dist目錄下去建立一個html文件,而後去引用打包後的js吧,這不合理,實際開發中也不會這樣
咱們須要實現html打包功能,能夠經過一個模板實現打包出引用好路徑的html來git
npm install --save-dev html-webpack-plugin clean-webpack-plugin // webpack.config.js const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'app', 'index.tmpl.html'),// 源模板文件 filename:'index.html', //生成的html存放路徑,相對於 path minify:{ //壓縮HTML文件 removeComments:true, //移除HTML中的註釋 collapseWhitespace:false //刪除空白符與換行符 }, //chunks:['index', 'vendor'], // 多入口的html文件用chunks這個參數來區分 }) ]
entry: { index: './src/index.js', login: './src/login.js' }, output: { // [name]就能夠將出口文件名和入口文件名一一對應 filename: '[name]-[hash].js', // 打包後會生成index.js和login.js文件 path: path.resolve('dist') }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['index'] // 對應關係,index.js對應的是index.html }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'] // 對應關係,login.js對應的是login.html }) ]
css文件須要額外的loader支持github
npm install --save-dev style-loader css-loader // webpack.config.js module.exports = { module: { rules: [ { test: /\.css$/, use: [ // 從右向左解析 'style-loader', 'css-loader' ] } ] } }; // 在入口文件 main.js 加入: import './style.css';
打包後的css文件是以行內樣式style的標籤寫進打包後的html頁面web
所有打包到一個文件,太多會影響加載速度,須要把文件拆分shell
npm install --save-dev mini-css-extract-plugin // webpack.config.js const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // CSS文件單獨提取出來 module: { rules: [ { test: /\.css$/, use: [ // 將 css 用 link 的方式引入就再也不須要 style-loader MiniCssExtractPlugin.loader, "css-loader" ], include: path.resolve(__dirname, 'app'), // 限制範圍,提升打包速度 exclude: /node_modules/ }, ] } new MiniCssExtractPlugin({ filename: `css/[name]-[contenthash].css`, }),
添加 CSS3 前綴
經過 postcss 中的 autoprefixer 能夠實現將 CSS3 中的一些須要兼容寫法的屬性添加響應的前綴,這樣省去咱們很多的時間npm
npm install --save-dev postcss-loader autoprefixer
在項目根目錄下建立一個 postcss.config.js 文件
// postcss.config.js module.exports = { plugins: [require('autoprefixer')] // 引用該插件便可了 } // webpack.config.js { test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] }
npm install --save-dev file-loader url-loader // webpack.config.js module: { rules: [ { test: /\.(png|svg|jpg|gif)$/, //use: ['file-loader'] use: [ { // url-loader內置了file-loader loader: 'url-loader', options: { limit: 8192, // 小於8k的圖片自動轉成base64格式,而且不會存在實體圖片 outputPath: 'images/' // 圖片打包後存放的目錄 } } ] }, ] ] // main.js import Icon from './icon.png';
頁面中常常會用到img標籤,img引用的圖片地址也須要一個loader來幫咱們處理好
npm install --save-dev html-withimg-loader module.exports = { module: { rules: [ { test: /\.(htm|html)$/, use: 'html-withimg-loader' } ] } }
這樣再打包後的html文件下img就能夠正常引用圖片路徑了
svg圖片均可以經過file-loader來解析,樣式中引入了這類格式的圖標或者圖片都沒有問題了,img若是也引用svg格式的話,配合上面寫好的html-withimg-loader就都沒有問題了
file-loader 和 url-loader 能夠接收並加載任何文件,而後將其輸出到構建目錄
// webpack.config.js { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ 'file-loader' ] } // style.css @font-face { font-family: 'MyFont'; src: url('./Omnes_Light.otf') format('woff2'); font-weight: 600; font-style: normal; }
NodeJS,JSON 支持其實是內置
導入 CSV、TSV 和 XML
npm install --save-dev csv-loader xml-loader //webpack.config.js { test: /\.(csv|tsv)$/, use: [ 'csv-loader' ] }, { test: /\.xml$/, use: [ 'xml-loader' ] } // main.js // 所導入的 Data 變量將包含可直接使用的已解析 JSON import Data from './data.xml'; // JSON, CSV, TSV, XML
css的hash命名必須使用contenthash,保證即便css文件所處的模塊裏就算其餘文件內容改變,只要css文件內容不變,那麼不會重複構建
css 若是使用style-loader將樣式添加到js文件中,在編寫樣式的時候能夠享受熱更新的效果,若是將樣式提取,須要手動刷新。
方法二:在入口文件中引入html文件,並使用raw-loader對html文件進行處理,實現html熱更新
html自動更新
一、安裝raw-loader
npm install --save-dev raw-loader
二、在webpack.config.js中配置raw-loader
rules: [ ...... { test: /\.(htm|html)$/, use: [ 'raw-loader' ] } ...... ]
三、在入口文件index.js文件中引入index.html文件
import '../template/index.html'
在實際開發中,常用 ES6 去寫代碼,這樣會提升咱們寫代碼的速度,不過爲了向後兼容低版本瀏覽器,須要 Babel 轉換成兼容的代碼
npm install -save-dev babel-core babel-loader babel-preset-env babel-preset-stage-0 babel-preset-react
代碼不只僅包含ES6還有以後的版本和那些僅僅是草案的內容,因此咱們能夠經過一個.babelrc文件來配置一下
// .babelrc { "presets": ["env", "stage-0"] // 從右向左解析 } // webpack.config.js module.exports = { module: { rules: [ { test:/\.js$/, use: 'bable-loader', include: /src/, // 只轉化src目錄下的js exclude: /node_modules/ // 排除掉node_modules,優化打包速度 } ] } }
npm install --save-dev webpack-merge
新建 webpack.common.js、webpack.dev.js、webpack.prod.js
把 webpack.config.js 文件內容分爲公共代碼、開發代碼、生產代碼
npm install --save-dev optimize-css-assets-webpack-plugin // webpack.prod.js const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin'); plugins: [ new OptimizeCSSPlugin({ cssProcessorOptions: {safe: true} }), ]
npm install --save-dev copy-webpack-plugin
// webpack.prod.js
const copyWebpackPlugin = require('copy-webpack-plugin');
new copyWebpackPlugin([{
from:__dirname+'/src/public',//打包的靜態資源目錄地址 to:'./public' //打包到dist下面的public
}]),
一、Cannot use [chunkhash] or [contenthash] for chunk in '[name]-[chunkhash].js' (use [hash] instead)
解決方法:
二、Refusing to install package with name "react" under a package also called "react".
解決方法:package.json name 的值不能跟npm的包名相同,同時把 package-lock.json 的 name 修改
三、img 和 css 的圖片路徑不對
若是是在css文件裏引入的如背景圖之類的圖片,就須要指定一下相對路徑
module: { rules: [ { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { /* * 複寫 css 文件中資源路徑 * 由於 css 文件中的外鏈是相對與 css 的, * 咱們抽離的 css 文件在可能會單獨放在 css 文件夾內 * 引用其餘如 img/a.png 會尋址錯誤 */ publicPath: '../' } }, { loader: "css-loader" }, { loader: "postcss-loader" } ], include: path.resolve(__dirname, 'src'), exclude: /node_modules/ } ] }