webpack 是利用loader 來處理各類資源的,wepback的配置基本上就是爲各類資源文件,指定不一樣類型的loader。css
1,處理csshtml
最基本的css 處理loader 是css-loader , style-loader. css-loader 處理的是css 中的@import 和url, 根據路徑(相對路徑)找到相應的資源,但它不處理具體的資源,好比,img, 是由file-loader或url-loader 來處理的,這個之後再說. style-loader則是把打包後的css文件插入到html中,具體的方法是,它會生成一個內聯的style 標籤,而後把css注入到這個style標籤中,它實現了模塊熱更新,修改css樣式的時候,頁面不會強制刷新,就能看到變化。那就npm install css-loader style-loader --save-dev 安裝它們。 安裝完成後,在webpack中進行配置。配置文件中有一個module屬性,module 屬性下面有一個rules 屬性,它是一個數組,loaders 的配置寫在它的裏面,每個配置項都是一個對象,test 屬性, 值是正則表達式,指明要處理哪一種文件,use 屬性,使用哪種loader, 最簡單的配置以下vue
const htmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { module: { rules: [ { test: /\.css$/, // 正則表達式,指明要處理的文件類型 use: ['style-loader', 'css-loader'] // 處理資源所使用的loader, 要注意loader的順序,從右向左執行 } ] }, devServer: { contentBase:'build', proxy: { '/api': 'http://102.03.34.58/api' }, port: 9000, // 設置端口號 stats: 'errors-only', // 只有產生錯誤的時候,才顯示錯誤信息,日誌的輸出等級是error. overlay: true // 當有編譯錯誤的時候,在瀏覽器頁面上顯示。 }, plugins: [ new htmlWebpackPlugin() ] }
寫一點css樣式,看配置有沒有生效,在src 目錄下,新建一個css文件夾,裏面寫一個style.css文件,隨便寫一點樣式,node
body { background: blue; }
而後在index.js 中引入import ‘./css/style.css’.webpack
// 引入css 樣式 import './css/style.scss'; import component from './component'; document.body.appendChild(component())
npm run dev 啓動服務器,能夠看到頁面有了背景色,這時咱們能夠隨便更改body的背景色,頁面也會時時作出了變化,很是方便開發。web
固然,你可能使用css 預處理器, less, sass stylus等, 這也簡單,安裝相應的loader 就能夠了,正則表達式
less: npm install less less-loader --save-dev, npm
sass: npm install node-sass, sass-loader --save -dev,json
stylus, npm install stylus, stylus-loader --save-dev,api
而後在use中增長一條相應的loader
rules: [ { test: /\.css$/, // 正則表達式,指明要處理的文件類型 use: ['style-loader', 'css-loader'] // 處理資源所使用的loader, 要注意loader的順序,從右向左執行 }, { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }, { test: /\.styl$/, use: ['style-loader', 'css-loader', 'stylus-loader'] } ]
最後再來講一下PostCSS, 它的配置稍微麻煩一點,由於PostCSS是由插件來起做用的,使用哪一個功能,就要安裝哪一個插件,若是隻安裝postcss-loader, 它並不起做用,這和babel-loader同樣, 好比要使用添加瀏覽器廠商前綴的功能, 在安裝postcss, postcss-loader 後,還要安裝對應的插件autoprefixer , npm install postcss, postcss-loader, autoprefixer --save-dev. 安裝完成後,就要進行配置。對於純css 來講,咱們最早使用postcss-loader, 因此postcss-loader要放到最右邊,可是又不能只寫一個postcss-loader 放在那裏,由於它本身不起做用,須要對postcss-loader進行配置。配置的方式有兩種,一種是在webpack的配置文件中,一個是單獨給postcss寫一個配置文件。
若是在wepback的配置文件中配置postcss-loader,那postcss-loader 就不能是一個字符串了,要是一個對象, loader屬性 是咱們指定的loader, options 就是咱們指定的配置項,對於postcss-loader 來講,它的配置項是plugins, 使用到的插件, 是一個函數,返回一個數組,數組中就包括用到的插件。
{ test: /\.css$/, use: ['style-loader', 'css-loader', { // 使用對象對postcss-loader進行配置,對象有兩個屬性loader, options // loader屬性就是指定使用的loader, options 就是該loader的配置項,也是一個對象 loader: 'postcss-loader', options: { plugins: () => ([ require('autoprefixer')() ]) } } ] }
可是當咱們使用不少插件進行開發,這樣在配置文件中進行配置就很麻煩了,也會致使配置文件比較龐大,這時就要使用PostCSS配置文件,它的配置文件有不少格式,json, yml, js的均可以,有興趣的能夠看一下官方文檔。我在這裏就使用postcss.config.js. 在項目根目錄下創建一個postcss.config.js 文件,它的格式以下,module-export 出一個帶有plugins屬性的對象。plugins屬性也是一個對象,屬性名就是使用的插件的名稱,屬性值是一個對象,對這個插件的配置。
module.exports = { plugins: { "autoprefixer": { browsers: [ // 加這個後能夠出現額外的兼容性前綴 "> 0.01%" ] } } }
使用配置文件後,webpack的配置文件還原到之前的狀態,
{ test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] }
如今在style.css中給body, 添加box-sizing: border-box; 看一下效果。
body { background: blue; box-sizing: border-box; }
打開瀏覽器控制檯,能夠看到添加了webkit- 的瀏覽器廠商前綴。
當使用css 預處理的時候,它要放到預處理器loader 的後面, 也就是說,先使用預處理器loader, 再使用postcss-loader. 固然配置仍是同樣的。以scss 爲例
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] }
可是這裏會存在一個問題,就是當樣式文件中,有@import 的時候,你會發現postcss-loader 並無起對import 進來的文件起做用,這時在css 文件夾中,再建一個文件夾,box.css
div { display: flex; width: 200px; height: 200px; border: 1px solid blue; }
而後在style.css 裏面@import 引入box.css;
/* @import 語句結尾要加分號 */ @import url(box.css); body { box-sizing: border-box; }
打開瀏覽器控制檯,找到div.css的樣式,你會發現display:flex 並無加前綴。
這時要給css-loader 設置一個屬性,importLoaders, 它的值爲一個數字,表示css-loader 前面有幾個loader 要處理,對於純css來講,它前面有一個loader, postcss-loader, 因此importLoaders 的取值爲1.
{ test: /\.css$/, use: ['style-loader', { loader: 'css-loader', options: { importLoaders: 1 } }, 'postcss-loader'] }
可是對於css預處理器來講,css-laoder 前面有個loader, postcss-loader 和預處理器loader,因此importLoaders的取值爲2.
{ test: /\.scss$/, use: ['style-loader', { loader: 'css-loader', options: { importLoaders: 2 } }, 'postcss-loader', 'sass-loader'] }
2,處理圖片
處理圖片主要用到兩個loader: url-loader style-loader. url-loader的做用是把圖片轉化成base64編碼的字符串,而後內嵌到到js文件中。 file-loader 則是把圖片打包成一個個單獨的圖片文件,並返回它們的路徑。可是這裏有一個問題,我想把小的圖片內嵌到js中, 大的圖片打包成一個個單獨的文件,怎麼辦?這時須要對url-loader進行配置,它有一個limit屬性,取值爲多少k, 表示的意思時,當小於limit時,直接把圖片打包到js中,當大於limit時,就使用file-loader 打包成一個單獨的文件,固然咱們也能夠給打包成的圖片起一個名字,那就要配置name屬性,當使用file-loader 生成圖片的時候,它會生成一個MD5 的hash值,咱們能夠利用這個hash值給文件命名,name: 「[name].[hash].[ext]」, name: 要打包的圖片之前的文件名,hash file-loader 生成的hash值,ext, 打包後的圖片之前的後綴名。固然,咱們想把圖片統一打包到一個文件夾中。能夠name 放一個文件夾名 ‘img/[name].[hash].[ext]’
{ test: /\.(jpg|png|svg)$/, use: { loader: 'url-loader', options: { limit: 2000, name: '/images/[name].[hash].[ext]' } } }
3,處理字體
Fonts 的處理方式和image的處理方式一致,也是url-loader, file-loader,
{ test: /\.(ttf|eot|woff|woff2)$/, use: { loader: "url-loader", options: { limit: 50000, mimetype: "application/font-woff", name: "./fonts/[name].[ext]" } } }
4, 處理js
js的處理用到的loader 是babel-loader,babel-loader 要依賴@babel/core, 如今babel升級到7了,之前的babel-core 要改爲@babel/core, 感受babel 7 是把babel 全部功能都放到了@babel的命名空間下,全部的presets 和plugins 都以@babel 開始,而後是/, 最後纔是相應的preset或plugin. 先安裝上babel-loader @babel/core再說, npm install babel-loader @babel/core --save-dev 而後在webpack的配置文件中配置一下,
{ test: /\.js$/, loader: 'babel-loader' }
這時執行一下npm run build, 你會發現有兩個問題,一是打包很是慢,由於 webpack 進行打包的時候,會把全部的js代碼都會打包一下,包括node_modules 下面的代碼,可是node_modules下面的代碼根本就沒有必要進行打包,因此要排除掉, 要用到 exclude 配置項,我以爲使用include 更好,include是表示要打包的代碼,咱們書寫的代碼在src下面,因此include 配置成src 目錄就能夠了。
{ test: /\.js$/, loader: 'babel-loader', include: path.join(__dirname, 'src'), exclude: path.join(__dirname, 'node_modules'), }
二是打包後的代碼和之前的代碼並無多少不一樣?這是由於@babel/core 自己不起做用,而是要依賴插件,一個一個插件寫起來太麻煩,因此babel 提供了插件的集合presets @babel/preset-env, npm install @babel/preset-env --save-dev, 安裝成功後,怎麼告訴babel-loader 使用presets 呢? 使用babel的配置文件 .babelrc, 在項目根目錄想創建.babelrc, 內容以下,
{ "presets": [ "@babel/preset-env" ] }
有時候,你想使用最新的功能,它並無包含在preset-env中,那就要單獨安裝babel的插件了,你想使用什麼功能,就安裝什麼的插件,好比使用 class properties ,就是安裝
{ "presets": [ "@babel/preset-env" ], "plugins": [ "@babel/plugin-proposal-class-properties" ] }
5 配置resolve, 主要是簡化引入組件或庫的方式
當引入css 文件的時候, 要寫import './style.css' ,文件的後綴名也要寫全,比較麻煩。不想寫後綴,怎麼辦, 就要在resolve中配置extensions,'.css', 只要引入文件的時候,不想寫後綴,就要在extensions 中配哪類文件的後綴
resolve: { extensions: ['.css', '.js', '.json', '.vue'] }
resolve 的配置項和module ,plugins 一個等級, 它還有一個比較經常使用的配置項是alias別名,當在代碼文件解析時,若是碰到一個名字,它實際指代的另一個內容,好比vue的配置文件中,alias 配置了'vue', 當在代碼中,import vue from 'vue' 時,它引用 就是alias 中配置的vue. 還有就是當咱們引入一個模塊時,層級太深, import '../../../css/index.css', 這時就能夠聲明一個alias, 指代一個文件夾
resolve: { extensions: ['.css', '.js', '.json', '.vue'], alias: { '@': 'src' } }