打包工具:Webpack
參考:
官網:https://webpack.js.org/guides/getting-started/
原文:https://segmentfault.com/a/1190000021395777
本文demo(webpack5):https://gitee.com/open_-_code/webpack_demo.git
webpack demo
1 初始化專案
初始化npm
npm init -y
安裝依賴
npm install webpack webpack-cli --save-dev
建立src檔案,src下建立index.js
// index.js console.log('hello webpack')
配置package.json
"scripts": { "build": "webpack" },
執行npm run build
此時如果生成了一個dist資料夾,並且內部含有main.js說明已經打包成功了
2 配置自己的配置
新建一個webpack.config.js
// webpack.config.js const path = require('path'); module.exports = { mode:'development', // 開發模式 entry: './src/index.js', //入口檔案 output: { filename: 'main.js', // 打包後的檔名稱 path: path.resolve(__dirname, 'dist'), // 打包後的目錄 }, };
更改package.json
"scripts": { "build": "webpack --config webpack.config.js" },
執行npm run build,其中dist
資料夾中的main.js
就是我們需要在瀏覽器中實際執行的檔案
3 配置html模板
為了快取,日常開發時,webpack.config.js往往會這樣配置
// webpack.config.js const path = require('path'); module.exports = { mode:'development', // 開發模式 entry: './src/index.js', // 入口檔案 output: { filename: '[name].[hash:8].js', // 打包後的檔名稱 path: path.resolve(__dirname, 'dist'), // 打包後的目錄 }, };
你會發現打包好的js檔案的名稱每次都不一樣
webpack打包出來的js檔案我們需要引入到html中,但是每次我們都手動修改js檔名顯得很麻煩,因此我們需要一個外掛來幫我們完成這件事情
npm i -D html-webpack-plugin
新建資料夾public,
裡面新建一個index.html
引入外掛html-webpack-plugin,修改webpack.config.js
// webpack.config.js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode:'development', // 開發模式 entry: './src/index.js', // 入口檔案 output: { filename: '[name].[hash:8].js', // 打包後的檔名稱 path: path.resolve(__dirname, 'dist'), // 打包後的目錄 }, plugins:[ new HtmlWebpackPlugin({ template:path.resolve(__dirname,'./public/index.html') }) ] };
執行打包命令,打包生成的js檔案已經被自動引入html檔案中
多檔案入口開發,修改webpack.config.js
// webpack.config.js plugins:[ new HtmlWebpackPlugin({ template:path.resolve(__dirname,'./public/index.html'), filename:'index.html', chunks:['main'] // 與入口檔案對應的模組名 }), new HtmlWebpackPlugin({ template:path.resolve(__dirname,'./public/header.html'), filename:'header.html', chunks:['header'] // 與入口檔案對應的模組名 }), ]
執行打包命令生成目錄
每次執行npm run build 會發現dist資料夾裡會殘留上次打包的檔案,這裡我們推薦一個plugin來幫我們在打包輸出前清空資料夾clean-webpack-plugin
npm i -D clean-webpack-plugin
// webpack.config.js const {CleanWebpackPlugin} = require('clean-webpack-plugin') module.exports = { // ...省略其他配置 plugins:[new CleanWebpackPlugin()] }
4 引入css
我們的入口檔案是js,所以我們在入口js中引入我們的css檔案
// index.js import '/src/assets/index.css' import '/src/assets/index.less' console.log('hello webpack')
同時我們也需要一些loader來解析我們的css檔案
npm i -D style-loader css-loader
如果我們使用less來構建樣式,則需要多安裝兩個
npm i -D less less-loader
// webpack.config.js module.exports = { // ...省略其他配置 module:{ rules:[ { test:/\.css$/, use:['style-loader','css-loader'] // 從右向左解析原則 }, { test:/\.less$/, use:['style-loader','css-loader','less-loader'] // 從右向左解析原則 } ] } }
執行打包命令,瀏覽器開啟dist下的index.html
4.1 為css新增瀏覽器字首
npm i -D postcss-loader autoprefixer
// webpack.config.js module.exports = { // ...省略其他配置 module:{ rules:[ { test:/\.less$/, use:['style-loader','css-loader','postcss-loader','less-loader'] // 從右向左解析原則 } ] } }
根目錄下建立postcss.config.js
// postcss.config.js module.exports = () => { return { plugins: { 'autoprefixer': { overrideBrowserslist: ['Android >= 4.0', 'iOS >= 7'] }, } } }
這時候我們發現css通過style標籤的方式新增到了html檔案中,但是如果樣式檔案很多,全部新增到html中,難免顯得混亂。這時候我們想用把css拆分出來用外鏈的形式引入css檔案怎麼做呢?這時候我們就需要藉助外掛來幫助我們
4.2 拆分css
webpack 4.0以前,我們通過extract-text-webpack-plugin
外掛,把css樣式從js檔案中提取到單獨的css檔案中。webpack4.0以後,官方推薦使用mini-css-extract-plugin
外掛來打包css檔案
npm i -D mini-css-extract-plugin
// webpack.config.js const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { //...省略其他配置 module: { rules: [ { test:/\.css$/, use:[MiniCssExtractPlugin.loader,'css-loader','postcss-loader'] // 從右向左解析原則 }, { test:/\.less$/, use:[MiniCssExtractPlugin.loader,'css-loader','less-loader','postcss-loader'] // 從右向左解析原則 }, ] }, plugins: [ new MiniCssExtractPlugin({ filename: "[name].[hash].css", chunkFilename: "[id].css", }) ] }
5 打包圖片、字型、媒體等檔案
file-loader
就是將檔案在進行一些處理後(主要是處理檔名和路徑、解析檔案url),並將檔案移動到輸出的目錄中
url-loader
一般與file-loader
搭配使用,功能與 file-loader 類似,如果檔案小於限制的大小。則會返回 base64 編碼,否則使用 file-loader 將檔案移動到輸出的目錄中
// webpack.config.js module.exports = { // 省略其它配置 ... module: { rules: [ // ... { test: /\.(jpe?g|png|gif)$/i, //圖片檔案 use: [ { loader: 'url-loader', options: { limit: 10240, fallback: { loader: 'file-loader', options: { name: 'img/[name].[hash:8].[ext]' } } } } ] }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, //媒體檔案 use: [ { loader: 'url-loader', options: { limit: 10240, fallback: { loader: 'file-loader', options: { name: 'media/[name].[hash:8].[ext]' } } } } ] }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i, // 字型 use: [ { loader: 'url-loader', options: { limit: 10240, fallback: { loader: 'file-loader', options: { name: 'fonts/[name].[hash:8].[ext]' } } } } ] }, ] } }
6 用babel轉義js檔案
npm install -D babel-loader @babel/core @babel/preset-env
-
- 注意
babel-loader
與babel-core
的版本對應關係
babel-loader
8.x 對應babel-core
7.xbabel-loader
7.x 對應babel-core
6.x
// webpack.config.js module.exports = { // 省略其它配置 ... module:{ rules:[ { test:/\.js$/, use:{ loader:'babel-loader', options:{ presets:['@babel/preset-env'] } }, exclude:/node_modules/ }, ] } }
上面的babel-loader
只會將 ES6/7/8語法轉換為ES5語法,但是對新api並不會轉換 例如(promise、Generator、Set、Maps、Proxy等)
cnpm i @babel/polyfill -D
// webpack.config.js const path = require('path') module.exports = { entry: ["@babel/polyfill",path.resolve(__dirname,'./src/index.js')], // 入口檔案 }
over!!