项目初始化 安装webpack、webpack-cli
1 npm i webpack webpack-cli -D
新建src/index.js
文件,根目录新建webpack.config.js
1 2 3 4 5 6 7 8 9 10 11 const path = require ('path' )module .exports = { entry : './src/index.js' , output : { path : path.resolve(__dirname, 'dist' ), filename : 'build.js' } }
loader的使用 css处理 postcss-loader,一般配合 Autoprefixer 使用,自动获取浏览器的流行度和能够支持的属性,并根据这些数据帮你自动为 CSS 规则添加前缀
1 2 npm i style-loader css-loader postcss-loader -D npm i autoprefixer -D
新建 postcss.config.js 配置文件
1 2 3 4 5 6 module .exports = { plugins : [ require ('autoprefixer' ) ] }
webpack.config.js:
1 2 3 4 5 6 7 8 9 10 module .exports = { module : { rules : [ { test : /\.css$/ , use: ['style-loader' , 'css-loader' , 'postcss-loader' ] } ] } }
打包less/sass、scss文件类似,只需安装 less-loader/sass-loader 即可。less-loader/sass-loader 放在 postcss-loader 之后
sass-loader
requires you to install either Dart Sass or Node Sass on your own (more documentation can be found below).
文件处理 图片
背景图片使用 type 设置打包类型;src 使用 require('./assets/img.png').default
,webpack 默认使用 esModule 引用图片对象而不是图片路径
type 设置 asset/resource
会生成图片原文件,asset/inline
会打包成 base64 格式,通过 parser/dataUrlCondition/maxSize 判断是否转为 base64 格式
1 2 3 { test : /\.(png|svg|gif|jpe?g)$/ , type: 'asset/resource' }
webpack5.x 已弃用 url-loader、file-loader,踩半天坑才查到。https://webpack.docschina.org/guides/asset-modules/
可通过 file-loader 的 options 来设置打包图片的路径和名称
url-loader 会将图片打包为 base64 的格式,可减少请求次数,如果图片过大会影响打包体积,通过设置 limit 根据文件大小来判断是否转为 base64格式
5.x版本通过设置 generator 自定义文件输出名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 module .exports = { module : { rules : [ { test : /\.css$/ , use: ['style-loader' , 'css-loader' , 'postcss-loader' ] }, { test : /\.(png|svg|gif|jpe?g)$/ , type: 'asset/resource' , generator : { filename : 'img/[hash][ext][query]' }, parser : { dataUrlCondition : { maxSize : 24 * 1024 } } } ] } }
图标字体类似
babel 安装
1 npm i babel-loader @babel/core @babel/preset-env
规则
1 2 3 4 5 6 7 8 9 10 module .exports = { rules : [ { test : /\.js$/ , exclude: /node_modules/ , use: ['babel-loader' ] } ] }
新建 babel.config.json
文件
1 2 3 { "presets" : ["@babel/preset-env" ] }
加载 vue 文件 1 npm i -D vue vue-loader vue-template-compiler
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <template> <div> <h2 class="title">{{title}}</h2> </div> </template> <script> export default { name: "App", data() { return { title: 'title' } }, } </script> <style scoped> .title { color: red; } </style>
index.js
1 2 3 4 5 6 import Vue from 'vue' import App from './App.vue' new Vue({ render : h => h(App) }).$mount('#app' )
此时打包会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 File was processed with these loaders: * ./node_modules/vue-loader/lib/index.js You may need an additional loader to handle the result of these loaders. | > <div> | <h2 class="title">{{title}}</h2> | </div> @ ./src/App.vue 1:0-94 11:2-8 12:2-17 @ ./src/index.js 2:0-28 5:13-16 ERROR in ./src/App.vue Module Error (from ./node_modules/vue-loader/lib/index.js): vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config. @ ./src/index.js 2:0-28 5:13-16 1 error has detailed information that is not shown. Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.
需要配合 VueLoaderPlugin 使用
1 2 3 const VueLoaderPlugin = require ('vue-loader/lib/plugin-webpack5.js' )new VueLoaderPlugin()
如需使用 css 预编译器编写 vue 代码,需要安装相应的 loader
常用插件 https://webpack.docschina.org/plugins/
html-webpack-plugin
清空 dist 文件目录
clean-webpack-plugin
自定义打包 html 模板
DefinePlugin
定义全局变量,import { DefinePlugin } from ‘webpack’
copy-webpack-plugin
拷贝文件或者是整个目录到输出文件夹,https://webpack.docschina.org/plugins/copy-webpack-plugin/
uglifyjs-webpack-plugin
压缩 js 代码体积,https://www.npmjs.com/package/uglifyjs-webpack-plugin
proxy 代理 对于跨域的请求可以用 devServer/proxy 来解决
安装 webpack-dev-server,webpack.config.js 做以下配置,这样就可以友好的请求网址了
1 2 3 4 5 6 7 8 9 10 11 12 module .exports = { devServer : { proxy : { '/api' : { target : 'https://api.github.com' , pathRewrite : { '^/api' : '' }, changeOrigin : true } } } };
开发/生产环境配置
新建 webpack.common.js、webpack.dev.js、webpack.prod.js 文件
webpack.common.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 const path = require ('path' )const HtmlWebpackPlugin = require ('html-webpack-plugin' )const CopyWebpackPlugin = require ('copy-webpack-plugin' )module .exports = { entry : './src/index.js' , output : { path : path.join(__dirname, 'dist' ), filename : 'js/main.js' , publicPath : '/' }, plugins : [ new HtmlWebpackPlugin({ template : path.join(__dirname, 'public/index.html' ) }), new CopyWebpackPlugin({ patterns : [ { from : 'public' , globOptions : { ignore : ['**/index.html' ] } } ] }) ], module : { rules : [ { test : /\.css$/ , use: ['style-loader' , 'css-loader' , 'postcss-loader' ] }, { test : /\.(png|svg|gif|jpe?g)$/ , type: 'asset/resource' , generator : { filename : 'img/[hash][ext][query]' }, parser : { dataUrlCondition : { maxSize : 24 * 1024 } } }, { test : /\.js$/ , exclude: /node_modules/ , use: ['babel-loader' ] } ] } }
webpack.dev.js
1 2 3 4 5 6 7 8 9 10 const {merge} = require ('webpack-merge' )const common = require ('./webpack.common.js' )module .exports = merge(common, { mode : 'development' , devtool : 'source-map' , devServer : { hot : true } })
webpack.prod.js
1 2 3 4 5 6 7 8 9 10 11 12 13 const {merge} = require ('webpack-merge' )const common = require ('./webpack.common.js' )const { CleanWebpackPlugin } = require ('clean-webpack-plugin' )const UglifyjsWebpackPlugin = require ('uglifyjs-webpack-plugin' )module .exports = merge(common, { mode : 'production' , performance : false , plugins : [ new CleanWebpackPlugin(), new UglifyjsWebpackPlugin() ] })