此博客僅供自身學習使用
webpack介紹
根據入口文件的依賴關系,將資源引進來,形成chunk代碼塊,根據不同資源進行編譯,這個處理過程我們叫做打包,打包輸出的文件叫做bundle
webpack五個核心概念
entry 入口
output 出口
loader(類似於翻譯官,因為webpack本身只能識別js文件,所以需要loader將css,img等文件翻譯成webpack能看懂的)
plugins:插件(可以執行范圍更廣的任務,比如打包優化和壓縮等)
mode:相應環境下的配置
webpack初體驗:結論
打包樣式資源
在目錄下新建webpack.config.js
loader的配置:
打包html資源:(在plugins配置html-webpack-glugin)
loader和plugins的區別:
html-webpack-glugin的作用(自動生成html文件或復制某個文件下的html文件,自動導入js/css文件,作用就是無需自己導入文件,html-webpack-glugin幫我們做了這個事情)
步驟一:引入html-webpack-plugin
步驟二:在 plugins中引入 實例化的HtmlWebpackPlugin
打包圖片資源 (url-loader file-loader html-loader)
url-loader是基於file-loader的,所以要一起引入
url-loader是處理后綴為png|jpg|gif。並且可以限制低於8kb的轉換成base64
重新用hash值命名
html-loader 是處理html中的img圖片(負責在html引入img,從而能被url-loader處理)
08 打包其他資源(例如一些字體資源 等)
09 devServer(熱更新,自動編譯,自動打開瀏覽器,自動刷新瀏覽器)
10 開發環境基本配置(總結之前的基本配置) (注:是webpack開發環境的基本配置)
//運行項目的兩個指令: //webpack 會將打包結果輸出出去(build文件夾) //npx webpack-dev-server 只會在內存中編譯打包,沒有輸出 //loader 和 plugin 的不同:(plugin 一定要先引入才能使用) //loader:1. 下載 2. 使用(配置 loader) //plugins:1.下載 2. 引入 3. 使用 // resolve用來拼接絕對路徑的方法 const { resolve } = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') // 引用plugin module.exports = { // webpack配置 entry: './src/js/index.js', // 入口起點 output: { // 輸出 // 輸出文件名 filename: 'js/build.js', // __dirname是nodejs的變量,代表當前文件的目錄絕對路徑 path: resolve(__dirname, 'build'), // 輸出路徑,所有資源打包都會輸出到這個文件夾下 }, // loader配置 module: { rules: [ // 詳細的loader配置 // 不同文件必須配置不同loader處理 { // 匹配哪些文件 test: /\.less$/, // 使用哪些loader進行處理 use: [ // use數組中loader執行順序:從右到左,從下到上,依次執行(先執行css-loader) // style-loader:創建style標簽,將js中的樣式資源插入進去,添加到head中生效 'style-loader', // css-loader:將css文件變成commonjs模塊加載到js中,里面內容是樣式字符串 'css-loader', // less-loader:將less文件編譯成css文件,需要下載less-loader和less 'less-loader' ], }, { test: /\.css$/, use: ['style-loader', 'css-loader'], }, { // url-loader:處理圖片資源,問題:默認處理不了html中的img圖片 test: /\.(jpg|png|gif)$/, // 需要下載 url-loader file-loader loader: 'url-loader', options: { // 圖片大小小於8kb,就會被base64處理,優點:減少請求數量(減輕服務器壓力),缺點:圖片體積會更大(文件請求速度更慢) // base64在客戶端本地解碼所以會減少服務器壓力,如果圖片過大還采用base64編碼會導致cpu調用率上升,網頁加載時變卡 limit: 8 * 1024, // 給圖片重命名,[hash:10]:取圖片的hash的前10位,[ext]:取文件原來擴展名 name: '[hash:10].[ext]', // 問題:因為url-loader默認使用es6模塊化解析,而html-loader引入圖片是conmonjs,解析時會出問題:[object Module] // 解決:關閉url-loader的es6模塊化,使用commonjs解析 esModule: false, outputPath: 'imgs', }, }, { test: /\.html$/, // 處理html文件的img圖片(負責引入img,從而能被url-loader進行處理) loader: 'html-loader', }, // 打包其他資源(除了html/js/css資源以外的資源) { // 排除html|js|css|less|jpg|png|gif文件 exclude: /\.(html|js|css|less|jpg|png|gif)/, // file-loader:處理其他文件 loader: 'file-loader', options: { name: '[hash:10].[ext]', outputPath: 'media', }, }, ], }, // plugin的配置 plugins: [ // html-webpack-plugin:默認會創建一個空的html文件,自動引入打包輸出的所有資源(JS/CSS) // 需要有結構的HTML文件可以加一個template new HtmlWebpackPlugin({ // 復制這個./src/index.html文件,並自動引入打包輸出的所有資源(JS/CSS) template: './src/index.html', }), ], // 模式 mode: 'development', // 開發模式 // 開發服務器 devServer:用來自動化,不用每次修改后都重新輸入webpack打包一遍(自動編譯,自動打開瀏覽器,自動刷新瀏覽器) // 特點:只會在內存中編譯打包,不會有任何輸出(不會像之前那樣在外面看到打包輸出的build包,而是在內存中,關閉后會自動刪除) // 啟動devServer指令為:npx webpack-dev-server devServer: { // 項目構建后路徑 contentBase: resolve(__dirname, 'build'), // 啟動gzip壓縮 compress: true, // 端口號 port: 3000, // 自動打開瀏覽器 open: true, }, }
而生產環境的配置需要考慮以下幾個方面:
- 提取 css 成單獨文件
- css 兼容性處理
- 壓縮 css
- js 語法檢查
- js 兼容性處理
- js 壓縮
- html 壓縮
下面是生產環境下的配置
12、提取css單獨文件(之前的css文件都是通過css-loader編譯在js里面的)
引入 plugin mini-css-extract-plugin
13、css兼容性處理
首先要下載兩個包 npm i postcss-loader postcss-preset-env
14、壓縮css(plugin: optimize-css-assets-webpack-plugin )
15、js語法檢查eslint (npm i airbnb eslint-config-airbnb-base eslint-plugin-import eslint)
16 js兼容性處理eslint (npm i babel - loader @babel/core @babel/preset-env)
1、基本兼容性處理:@babel/preset-env
問題:只能轉換基本語法,如果是promise等就轉化不了
2、全部js兼容性處理 : @babel/polyfill(已經廢棄)
問題:直解決部分兼容性問題,但是將所有兼容性代碼都全部引入了,體積太大
3、需要做兼容性處理的就做:按需加載 --> core-js
最后是結合第一個和第三個一起實現的
17 壓縮html和js
生產環境下會自動壓縮js代碼
18、生產環境基本配置
const { resolve } = require('path') const MiniCssExtractorPlugin = require('mini-css-extract-plugin') const OptimiziCssAssetsWebpackPlugin = require('optimizi-css-assets-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') // 定義node.js的環境變量,決定使用browserslist的哪個環境 process.env.NODE_ENV = 'production' // 復用loader的寫法 const commonCssLoader = [ // 這個loader取代style-loader。作用:提取js中的css成單獨文件然后通過link加載 MiniCssExtractPlugin.loader, // css-loader:將css文件整合到js文件中 // 經過css-loader處理后,樣式文件是在js文件中的 // 問題:1.js文件體積會很大2.需要先加載js再動態創建style標簽,樣式渲染速度就慢,會出現閃屏現象 // 解決:用MiniCssExtractPlugin.loader替代style-loader 'css-loader', /* postcss-loader:css兼容性處理:postcss --> 需要安裝:postcss-loader postcss-preset-env postcss需要通過package.json中browserslist里面的配置加載指定的css兼容性樣式 在package.json中定義browserslist: "browserslist": { // 開發環境 --> 設置node環境變量:process.env.NODE_ENV = development "development": [ // 只需要可以運行即可 "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ], // 生產環境。默認是生產環境 "production": [ // 需要滿足絕大多數瀏覽器的兼容 ">0.2%", "not dead", "not op_mini all" ] }, */ { loader: 'postcss-loader', options: { ident: 'postcss', // 基本寫法 plugins: () => [ // postcss的插件 require('postcss-preset-env')(), ], }, }, ] module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build'), }, module: { rules: [ { test: /\.css$/, use: [...commonCssLoader], }, { test: /\.less$/, use: [...commonCssLoader, 'less-loader'], }, /* 正常來講,一個文件只能被一個loader處理 當一個文件要被多個loader處理,那么一定要指定loader執行的先后順序 先執行eslint再執行babel(用enforce) */ { /* js的語法檢查: 需要下載 eslint-loader eslint 注意:只檢查自己寫的源代碼,第三方的庫是不用檢查的 airbnb(一個流行的js風格) --> 需要下載 eslint-config-airbnb-base eslint-plugin-import 設置檢查規則: package.json中eslintConfig中設置 "eslintConfig": { "extends": "airbnb-base", // 繼承airbnb的風格規范 "env": { "browser": true // 可以使用瀏覽器中的全局變量(使用window不會報錯) } } */ test: /\.js$/, exclude: /node_modules/, // 忽略node_modules enforce: 'pre', // 優先執行 loader: 'eslint-loader', options: { // 自動修復 fix: true, }, }, /* js兼容性處理:需要下載 babel-loader @babel/core 1. 基本js兼容性處理 --> @babel/preset-env 問題:只能轉換基本語法,如promise高級語法不能轉換 2. 全部js兼容性處理 --> @babel/polyfill 問題:只要解決部分兼容性問題,但是將所有兼容性代碼全部引入,體積太大了 3. 需要做兼容性處理的就做:按需加載 --> core-js */ { // 第三種方式:按需加載 test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { // 預設:指示babel做怎樣的兼容性處理 presets: [ '@babel/preset-env', // 基本預設 { useBuiltIns: 'usage', //按需加載 corejs: { version: 3 }, // 指定core-js版本 targets: { // 指定兼容到什么版本的瀏覽器 chrome: '60', firefox: '50', ie: '9', safari: '10', edge: '17' }, }, ], }, }, { // 圖片處理 test: /\.(jpg|png|gif)/, loader: 'url-loader', options: { limit: 8 * 1024, name: '[hash:10].[ext]', outputPath: 'imgs', esModule: false, // 關閉url-loader默認使用的es6模塊化解析 }, }, // html中的圖片處理 { test: /\.html$/, loader: 'html-loader', }, // 處理其他文件 { exclude: /\.(js|css|less|html|jpg|png|gif)/, loader: 'file-loader', options: { outputPath: 'media', }, }, ], }, plugins: [ new MiniCssExtractPlugin({ // 對輸出的css文件進行重命名 filename: 'css/built.css', }), // 壓縮css new OptimiziCssAssetsWebpackPlugin(), // HtmlWebpackPlugin:html文件的打包和壓縮處理 // 通過這個插件會自動將單獨打包的樣式文件通過link標簽引入 new HtmlWebpackPlugin({ template: './src/index.html', // 壓縮html代碼 minify: { // 移除空格 collapseWhitespace: true, // 移除注釋 removeComments: true, }, }), ], // 生產環境下會自動壓縮js代碼 mode: 'production', }