Webpack入门系列(四)

94 阅读2分钟

本文主要是介绍如何搭建本地vue-cli。如果你对webpack不是很熟悉,请跳转前面三篇文章。 传送门:

好了,我们从头开始创建一个新的项目,用来搭建一个简单的vue-cli。

首先创建个webpack.config.js,然后简单配置一下

const path = require("path");

module.exports = {
  entry: path.resolve(__dirname, "./src/main.js"),
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].[contenthash].js",
    chunkFilename: "[name].[contenthash].[chunk].js",
  },
  module: {
    rules: [],
  },
  plugins: [],
};

我们开始增加loader

先从css开始

这里我们只是用less

pnpm i -D css-loader style-loader less-loader less postcss postcss-loader postcss-preset-env

image.png

配置postcss预设

module.exports = {
  plugins: [require("postcss-preset-env")],
};

别忘了在package.json配置要适配的浏览器版本

 "browserslist": [
    "> 1%",
    "last 2 version",
    "not dead"
  ]

css配置优化

pnpm i -D mini-css-extract-plugin css-minimizer-webpack-plugin

替换原本的style-loader image.png

html配置

pnpm i -D html-webpack-plugin 指定模板路径

new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "./public/index.html"),
    }),

js配置

pnpm i -D @babel/core babel-loader @vue/cli-plugin-babel

注意,这里的babel预设我们使用vue-cli已经配置好的@vue/cli-plugin-babel

image.png

image.png

js压缩,webpack自带TerserPlugin插件

new TerserPlugin()

vue文件解析

pnpm i -D vue-loader vue-style-loader vue-template-compiler 分别对应vue文件解析,vue中style解析,vue模板语法解析

const { VueLoaderPlugin } = require("vue-loader");
...
...

// 配置loader
{
        test: /\.vue$/,
        loader: "vue-loader",
        options: {
          cacheDirectory: path.resolve(__dirname, "../node_modules/.cache/vue-loader"),
        },
      },
      
// 使用plugin
new VueLoaderPlugin(),

eslint 配置

pnpm i -D eslint @babel/eslint-parser eslint-plugin-vue eslint-webpack-plugin

配置vue eslint预设

module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: ["plugin:vue/vue3-essential", "eslint:recommended"],
  parserOptions: {
    parser: "@babel/eslint-parser",
  },
};

配置plugin

  new EslintWebpackPlugin({
      ignorePath: path.resolve(__dirname, "./node_modules"),
      context: path.resolve(__dirname, "../src"),
      cache: true,
      cacheLocation: path.resolve(__dirname, "../node_modules/.cache/.eslintcache"),
    }),

配置开发环境

pnpm i -D webpack-dev-server

  devServer: {
   
    port: 3000,
    open: true,
    hot: true,
  },

我们来安装一下vue试一下

pnpm i vue

创建App组件

image.png

创建挂载文件

image.png

在html文件中创建挂载点

image.png

创建执行脚本

image.png

启动一下,发现没有安装webpack,尴尬了,赶紧安装一下pnpm i webpack webpack-cli 安装后启动一下

image.png

成功启动,

再加上路由试试

pnpm i vue-router

import { createWebHistory, createRouter } from "vue-router";

const routes = [
  {
    path: "/home",
    component: () => import("../views/Home.vue"),
  },
  {
    path: "/about",
    component: () => import("../views/About.vue"),
  },
];

const router = createRouter({
  routes,
  history: createWebHistory(),
});

export default router;

在主文件中进行注册

image.png

在app.vue组件中配置路由占位符

image.png

启动,查看控制台

image.png

有个警告,他说我们的__VUE_OPTIONS_API__,和__VUE_PROD_DEVTOOLS__没有配置 我们用webpack提供的definePlugin来配置

image.png

修改了配置文件,所以我们需要重新启动,警告解除。

但是当我们切换路由到/home后,刷新浏览器会报错

image.png

这里就是history路由模式的缺点,这个路径会往发送到服务器去请求资源,但是我们没有home这个文件,则会报错。

因为当前是开发模式,我们可以在devserver里进行配置historyApiFallback: true即可解决,重启再试一下,问题解决。

接下来,引入element-plus

安装pnpm install element-plus --save

开发中,我们可能不需要引入element中所有的组件,所以为了减小包体积,这里采用按需加载,可以参考官方文档进行配置

pnpm install -D unplugin-vue-components unplugin-auto-import 配置插件

image.png

引入一个button试试

image.png

发现没有样式,引入样式

image.png

成功引入

配置打包优化

开启压缩,代码分割,缓存

optimization: {
    minimize: isProduction,
    splitChunk: {
      chunks: "all",
      cacheGroups: {
        vue: {
          test: /[\\/]node_modules[\\/]vue(.*)?/,
          name: "vue-chunk",
          priority: 40,
        },
        element: {
          priority: 30,
          test: /[\\/]node_modules[\\/]element-plus[\\/]/,
          name: "element-chunk",
        },
        libs: {
          priority: 20,
          test: /[\\/]node_modules[\\/]/,
          name: "libs-chunk",
        },
      },
     
    },
     // 缓存
      runtimeChunk: {
        name: (entry) => `runtime~${entry.name}.js`,
      },
  },

配置devtool devtool: isProduction ? undefined : "cheap-module-source-map"

配置指定打包环境 pnpm i -D cross-env

"build": "cross-env NODE_ENV=production webpack build"

修改输出路径

 output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].[contenthash].js",
    chunkFilename: "static/js/[name].[contenthash].[chunk].js",
    assetModuleFilename: "static/media/[contenthash][ext][query]",
    clean: true,
  },
  
  
  ...
  
  
  new MinCssExtractPlugin({
      filename: "static/css/[name].[contenthash].css",
      chunkFilename: "static/css/[name].[contenthash].chunk.css",
    })
    
    ....
    
    
    cacheGroups: {
        vue: {
          test: /[\\/]node_modules[\\/]vue(.*)?/,
          name: "static/js/vue-chunk",
          priority: 40,
        },
        element: {
          priority: 30,
          test: /[\\/]node_modules[\\/]element-plus[\\/]/,
          name: "static/js/element-chunk",
        },
        libs: {
          priority: 20,
          test: /[\\/]node_modules[\\/]/,
          name: "static/js/libs-chunk",
        },
      },
    

build一下,看效果

image.png

好了,一个简单的本地vue-cli就搭建完成了