阅读 218

webpack5搭建vue3教程(使用webpack搭建vue项目的步骤)

webpack5已经出来有一阵了,可是vue-cli要等到5.0版本才引入webpack5,主要担心的是nodejs的polyfills问题,
在vue-cli 5.0稳定之前,先自己搭建一遍,一些惯例尽量和vue-cli保持一致,求同存异.
教程不面向新手,你需要了解一些基本的webpack知识,比如loader,plugins,resolve

1. 初始化

新建一个目录,在该目录下执行命令

npm init 复制代码

会提示你一些选项,除了入口文件默认是index.js,我们这里和vue-cli保持一直输入main.js,剩下的直接回车就好. 会在目录下生成一个package.json文件

image.png

image.png

2.搭建webpack环境

npm i webpack webpack-merge webpack-dev-serve webpack-cli -D 复制代码

webpack是必装的,这个就不用介绍了
webpack-merge 这个是用来合并webpack配置文件的,比如一般项目有三个webpack配置文件,一个基础的 打包图片 样式啥的,一个生产环境的,一个开发环境的.开发环境就需要把基础配置文件合并进来再export
webpack-dev-serve 提供一个本地serve服务器,webpack5自带了一个serve但是传言日志不好,暂时还是dev serve webpack-cli webpack-cli 可以让你在命令行中调用webpack

3.创建目录和文件

image.png

创建红框里的目录和文件,其中index.html为了一致性直接用的vue-cli的index.html.把对ico文件的link那一行删掉

<!DOCTYPE html> <html lang="">   <head>     <meta charset="utf-8">     <meta http-equiv="X-UA-Compatible" content="IE=edge">     <meta name="viewport" content="width=device-width,initial-scale=1.0">     <title><%= htmlWebpackPlugin.options.title %></title>   </head>   <body>     <noscript>       <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>     </noscript>     <div id="app"></div>     <!-- built files will be auto injected -->   </body> </html> 复制代码

当然,你也可以自己定义一个更简单的,比如这样

<!DOCTYPE html> <html lang="">   <body>     <div id="app"></div>   </body> </html> 复制代码

4.基本配置

我们先做一个最简单的配置,看看webpack能不能跑起来

webpack.common.js配置

const path = require('path') module.exports = env =>{     return {         entry:'./src/main.js',//入口文件         stats: 'errors-only',//仅错误时显示logo         output:{             filename: 'assets/js/[name].code.js',             chunkFilename: 'assets/js/[name].bundle.js',//动态导入 分离bundle 比如lodashjs配合注释import(/* webpackChunkName: "lodash" */ 'lodash') 会打包成lodash.bundle.js             path: path.resolve(__dirname, '../dist'),         }     } } 复制代码

webpack.prod.js配置

//const webpack = require('webpack'); const { merge } = require('webpack-merge'); const common = require('./webpack.common.js'); module.exports = env =>{     let pro_config = {         mode:'production',         // devtool:'source-map',//开启将会生成map文件     }     return merge(common(env),pro_config)  //合并配置 } 复制代码

main.js

console.log('this is mainjs') 复制代码

package.json

  "scripts": {     "build": "webpack  --config build/webpack.prod.js"   }, 复制代码

都是很基础的配置哈,大概说下逻辑.
当我们在命令行输入npm run build的时候,会执行webpack.prod.js文件,
在prod配置文件里,借助merge插件,会把webpack.common.js里的配置也执行起来.
在common文件里,入口是main.js,打包出口是dist目录 这时候我们执行run build 应该会看到新增加了一个目录,如图所示

image.png

5.根据业务需求配置插件

我们的目标是搭建一个类似vue-cli的脚手架,所以我们需要如下插件

vue-loader

loader 用于对模块的源代码进行转换,vue-loader当然就是对vue代码进行转换,让浏览器能够识别.
vue-loader除了在rules里配置外,还要在plugins配置下,是为了把其他定义的规则应用到vue文件里.

npm install vue@next -S npm install vue-loader@next @vue/compiler-sfc 复制代码

webpack.common.js文件:

const path = require('path') const { VueLoaderPlugin } = require('vue-loader') module.exports = env =>{     return {         entry:'./src/main.js',//入口文件         output:{             filename: 'assets/js/[name].code.js',             chunkFilename: 'assets/js/[name].bundle.js',//动态导入 分离bundle 比如lodashjs配合注释import(/* webpackChunkName: "lodash" */ 'lodash') 会打包成lodash.bundle.js             path: path.resolve(__dirname, '../dist'),         },         plugins:[             new VueLoaderPlugin()         ],         module:{             rules:[                 {                     test:/\.vue$/,                     loader:'vue-loader'                 },                 // 它会应用到普通的 `.js` 文件以及 `.vue` 文件中的 `<script>` 块             ]         }     } } 复制代码

HtmlWebpackPlugin

HtmlWebpackPlugin可以让打包后的JS自动引入html文件中

npm i -D html-webpack-plugin 复制代码

这个插件也属于生产和开发环境都用到的,所以在webpack.common.js文件里配置

const path = require('path') const { VueLoaderPlugin } = require('vue-loader') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = env =>{     return {         entry:'./src/main.js',//入口文件         output:{             filename: 'assets/js/[name].code.js',             chunkFilename: 'assets/js/[name].bundle.js',//动态导入 分离bundle 比如lodashjs配合注释import(/* webpackChunkName: "lodash" */ 'lodash') 会打包成lodash.bundle.js             path: path.resolve(__dirname, '../dist'),         },         plugins:[             new VueLoaderPlugin(),             new HtmlWebpackPlugin({                 template: path.join(__dirname, '../public/index.html'),                 filename: 'index.html',//输出的文件名             }),         ],         module:{             rules:[                 {                     test:/\.vue$/,                     loader:'vue-loader'                 },                 // 它会应用到普通的 `.js` 文件以及 `.vue` 文件中的 `<script>` 块             ]         }     } } 复制代码

bable-loader

这个就不多介绍了,能让你现在就用ES6 7 8的语法,官方教程

npm install -D babel-loader @babel/core @babel/preset-env webpack 复制代码

在webpack.common.js的rules里添加一条

module: {       rules: [         {           test: /\.vue$/,           loader: "vue-loader",         }, // 它会应用到普通的 `.js` 文件以及 `.vue` 文件中的 `<script>` 块         {           test: /\.m?js$/,           exclude: /(node_modules|bower_components)/,           use: {             loader: "babel-loader",             options: {               presets: ["@babel/preset-env"],             },           },         },       ],     }, 复制代码

resolve

resolve主要是配置如会解析模块.常用的有两个extensions和alias,一个配置后缀名,可以不带后缀.一个配置引入别名,不用逐层引入
在webpack.common.js文件里配置

resolve:{  //配置模块如会解析        extensions:['.vue','.js','.json'],//引入这些文件 可以不带后缀 按顺序解析        alias:{            '@':join('../src'), //@方式引入资源        }     }, 复制代码

image.png

资源模块

资源模块比如png svg jpg等图片或者txt等,webpack5之前都是用file-loader或者url-loader来处理.
webpack5现在会自动处理,不用再手动配置.小于8kb的资源视为inline资源处理,否则视为resource处理.
比如如果我们想规定小于6kb的图片才内联inline处理,否则就resource 引入.
webpack.common.js里

 {             test: /\.(png|svg|jpg|gif)$/,             type: 'asset',             parser: {                dataUrlCondition: {                    maxSize: 6 * 1024,//小于6kb的图片内联处理                }             }         }  复制代码

5.开发环境配置

上面主要是webpack.common.js基础配置,下面我们根据开发环境定制需要的配置.

friendly-errors-webpack-plugin

执行npm run serve成功之后,可以在控制台输出信息

const { merge } = require("webpack-merge"); const common = require("./webpack.common.js"); const FriendlyErrorsPlugin = require("friendly-errors-webpack-plugin"); const ip = require("ip"); let port = "8082"; module.exports = (env) => {   let dev_config = {     devtool: 'inline-source-map',//开启source map     mode: "development",     plugins: [       //运行成功,输出信息       new FriendlyErrorsPlugin({         compilationSuccessInfo: {           messages: [             `You application is running here http://${ip.address()}:${port} \r\nYou can also open local address http://localhost:${port}`,           ],           clearConsole: true,         },       }),     ],   };   return merge(common(env), dev_config); }; 复制代码

devserve

在devserve里我们可以指定端口啊,是否支持https,是否打卡浏览器窗口 在plugins下面增加一个同级的配置即可.

 devServer: {       host: "0.0.0.0",       port: port,       open:"http://localhost:" + port,//打开指定窗口       proxy: {         "/api": {           target: "http://www.xxx.com:8080/api",           secure: true, // 如果是https接口,需要配置这个参数           changeOrigin: true,           pathRewrite: { "^/finchinaAPP": "" },         },       },     }, 复制代码

cache

cache缓存生成的webpack模块和chunk,主要能提示构建速度.只在开发模式能用,默认是memory既缓存到内存中.
如果想自定义缓存策略,需要把cache的type值由memory改成filesystem.
比如修改默认缓存目录

const path = require('path'); module.exports = {   //...   cache: {     type: 'filesystem',     cacheDirectory: path.resolve(__dirname, '.temp_cache'),   }, }; 复制代码

css处理

因为生产环境的CSS需要压缩,这里还是分别配置好了.
先安装style-loader 把CSS插入到DOM中.

npm install --save-dev style-loader 复制代码

再安装css-loader 对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样.

npm install --save-dev css-loader 复制代码

最后在module的rules里增加一条规则

{           //解析器的执行顺序是从下往上(先css-loader再style-loader)           test: /\.css$/i,           use: [             "style-loader",             {               loader: "css-loader",               options: {                 esModule: false,                 modules: {                   auto: false, //modules 开关,移动端多页面模式关闭class hash命名                   localIdentName: "[local]_[hash:base64:8]", // 自定义生成的类名                 },               },             },           ],         }, 复制代码

sass-css处理

一般项目都会用到css处理器,所以光处理css是不够的,假如项目用的是sass-css,这么解决.
安装node-sass sass-loader

npm i node-sass -D npm install sass-loader sass webpack --save-dev 复制代码

在rulues里新增一个规则

 {         test: /.s[ac]ss$/i,         use: [           // 将 JS 字符串生成为 style 节点           'style-loader',           // 将 CSS 转化成 CommonJS 模块           'css-loader',           // 将 Sass 编译成 CSS           'sass-loader',         ],       }, 复制代码

less-css处理

如果用的是less-css 需要安装一个less-loader

npm install less less-loader --save-dev 复制代码

然后在rules里配置下

 {           test: /\.less$/i,           use: [             // compiles Less to CSS             "style-loader",             "css-loader",             "less-loader",           ],         }, 复制代码

到此,我们的开发环境就配置完了.

6.生产环境配置

webpack5相对于4自动化增强了,比如会自动清除输出目录下的历史文件,自动压缩JS等 css-loader sass-loader less-loader上面已经介绍过了就不多介绍了.

提取css

借助MiniCssExtractPlugin插件

npm install --save-dev mini-css-extract-plugin 复制代码

然后在plugins和css loader配置

plugins: [                     new webpack.DefinePlugin({                 'process.env.NODE_ENV': JSON.stringify('production')             }),             //提取CSS             new MiniCssExtractPlugin({                 filename:`assets/css/[name].style.css`,                 chunkFilename:`assets/css/[name].css`             }),         ],         module: {             rules: [                 {                     //解析器的执行顺序是从下往上(先css-loader再style-loader)                     test: /\.css$/,                     use: [                         MiniCssExtractPlugin.loader,                         {                             loader: 'css-loader',                             options: {                                 esModule: false,                                 modules:{                                     auto:false,//modules 开关,移动端多页面模式关闭class hash命名                                     localIdentName: '[local]_[hash:base64:8]',// 自定义生成的类名                                 }                             }                         },                     ]                 },                 {                     test: /\.scss$/,                     use: [                         MiniCssExtractPlugin.loader,                         'css-loader',                         'sass-loader'                     ]                 },                 {                     test: /\.less$/,                     use: [                         MiniCssExtractPlugin.loader,                                             'css-loader',                         'less-loader'                     ]                 },             ]         }, 复制代码

压缩css

webpack4使用的是OptimizeCSSAssetsPlugin,到了webpack5官方推荐使用CssMinimizerWebpackPlugin

 npm install css-minimizer-webpack-plugin --save-dev 复制代码

然后在module同级新增一个配置

optimization: {     minimizer: [       // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释       // `...`,       new CssMinimizerPlugin(),     ],   } 复制代码

其实我们生产环境可以直接配置minimize: true,也行.

代码分离Optimization

Optimization,webpack5默认的构建目标是web,如果是别的比如node项目或者electorn项目,需要增加一个target属性
比如构建node环境

module.exports = {   target: 'node', }; 复制代码

对于webpack的optimization,一般只关注optimization.splitChunks
splitChunks默认给我们配置了一套拆分规则

-   新的 chunk 可以被共享,或者模块来自于 `node_modules` 文件夹 -   新的 chunk 体积大于 20kb(在进行 min+gz 之前的体积) -   当按需加载 chunks 时,并行请求的最大数量小于或等于 30 -   当加载初始化页面时,并发请求的最大数量小于或等于 30 optimization: {     splitChunks: {       chunks: 'async',       minSize: 20000,       minRemainingSize: 0,       minChunks: 1,       maxAsyncRequests: 30,       maxInitialRequests: 30,       enforceSizeThreshold: 50000,       cacheGroups: {         defaultVendors: {           test: /[\/]node_modules[\/]/,           priority: -10,           reuseExistingChunk: true,         },         default: {           minChunks: 2,           priority: -20,           reuseExistingChunk: true,         },       },     },   }, } 复制代码

我们也可以根据实际项目情况,做些调整,比如默认20kb开始分割代码,改成30KB分割代码等

splitChunks: {                 minChunks: 2,  //模块至少使用次数                 cacheGroups: {                     vendor: {                         name: 'vendor',                         test: /[\\/]node_modules[\\/]/,                         chunks: 'all',                         priority: 2,  //2>0  nodulesmodules里的模块将优先打包进vendor                     },                     commons: {                         name: "commons",   //async异步代码分割 initial同步代码分割 all同步异步分割都开启                         chunks: "all",                         minSize: 30000,         //字节 引入的文件大于30kb才进行分割                             priority: 0,   //优先级,先打包到哪个组里面,值越大,优先级越高                     }                 }             } 复制代码

打包体积分析

打包后的代码,有时候文件比较大,需要分析下情况,这时候需要安装分析插件webpack-bundle-analyzer

npm install --save-dev webpack-bundle-analyzer 复制代码

然后配置只有监听到输入分析命令后才启动,不然每次打包都要启动

image.png

然后在package.json配置启动命令

"scripts": {     "serve": "webpack-dev-server  --hot   --config build/webpack.dev.js",     "dev": "webpack-dev-server --open --progress --config build/webpack.dev.js",     "build": "webpack  --config  build/webpack.prod.js",     "distanalyzer": "webpack --env.analyzer=true --config build/webpack.prod.js"   }, 复制代码

至此,大功搞定.

7.跑起来试一下

安装vue-router

npm install vue-router@4 复制代码

简单写两个页面,成功!

image.png


作者:折叠幸福
链接:https://juejin.cn/post/7034810358795599880


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐