使用 webpack5 自己一步一步实现 (vue3) vue-cli (脚手架工具)

790 阅读10分钟

大家好我是 Muddyrain ,一个前端小🔥,利用自己的见解来构建此项目,希望大家喜欢!

1. 首先第一步 - 使用 vscode 创建一个工作区当项目目录(我使用的目录文件夹名称:vue-cli) 且初始化 package.json 包文件

node 初始化 回车

npm init 
  • package name: (vue-cli) ------ 项目包的名称 默认就是文件夹目录名称
  • version: (1.0.0) ------ 项目版本 (大版本·次要版本·修订版本)
  • description: 自定义脚手架工具 ------ 项目描述信息
  • entry point: (index.js) ----- 项目入口文件 默认为 index.js 索引文件
  • test command: ----- 测试脚本
  • git repository: ----- git 源地址
  • keywords: cli webpack ----- npmjs 包网的搜索关键字
  • author: muddyrain ----- 这里就是此项目的作者
  • license: (ISC) ----- 开源许可证这里使用默认的 ISC 就好了

这里都填写完后 终端会再来一句提示 - 直接回车就好了

Is this OK? (yes) 

然后项目里就出现了一个文件名为 package.json 的文件

{
  "name": "vue-cli",
  "version": "1.0.0",
  "description": "自定义脚手架工具",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "cli",
    "webpack"
  ],
  "author": "muddyrain",
  "license": "ISC"
}

这里应该差不多都是一样的 如果不一样那就可以直接从这里复制过去。

2. 第二步 安装 webpack,webpack-cli 以及创建 webpack.config.js配置文件 以及 项目入口文件(index.js) 和 项目模板文件(index.html)

npm install webpack webpack-cli --save-dev

安装完成后 package.json中就会出现一个 devDependencies 这个对象 这里面的模块这是开发时需要的依赖,项目发布产生环境后不会进行打包带走的。另外项目目录里也会出现 node_modules这个node包模块目录

image.png

之后就可以直接在vscode工作区中 新建文件

image.png

image.png

image.png

<!-- 初始化项目模板用于 vue -->
<!DOCTYPE html>
<html lang="en">

<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>muddyrain</title>
</head>

<body>
    <div id="app"></div>
</body>

</html>

在这个文件中 我们使用 commonjs 规范来进行导出。 先初始化 webpack.config.js

const { Configuration } = require("webpack");
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
/**
 * @type {Configuration} -- 使用 jsDoc 用来代码类型提示
 */
const config = {
  mode: "development", // 当前环境模式 development 开发模式
  entry: resolve(__dirname, "./src/index.js"), // 入口文件 利用 path模块里的 resolve 来进行绝对路径
  output: {
    path: resolve(__dirname, "./dist/"), // 输出配置 一般都会输出到 dist 目录下
    filename: "js/chunk-[contenthash].js", // 这样的意思是 js 文件都会放在 js目录下 并且使用 chunk + hash的方式进行命名
    clean: true, // 每次打包前会清除一下之前打包的旧文件防止重复
  },
  plugins: [
    // html 插件 用于帮我们把打包好的 js 文件自动注入到模板里
    new HtmlWebpackPlugin({
      filename: "index.html", // 打包后文件名称
      template: resolve(__dirname, "./public/index.html"), // 模板地址路径
      inject: "body", // js文件插入 body里
    }),
  ],
};

module.exports = config;

这样就配置好了最基础的打包配置,配置好这些安装一些 webpack.config.js 里需要的依赖 (path: node环境自带的依赖不需要安装)

npm install html-webpack-plugin --save-dev

下面我们来配置下 package.json的scripts脚本

  "scripts": {
    "build": "webpack"
  },

这个默认就会去找 当前目录下的 webpack.config.js 如果我们写在了其他目录下 就需要这样 文件目录以及文件名字可以任意 当然必须需要以 package.json文件为基准去筛选路径

  "scripts": {
    "build": "webpack --config xxx/webpack.config.js"
  },

编译前我们可以在 src/index.js中写一些东西

console.log("哈哈哈,我是muddyrain,一个前端小🔥");

3. 接下来可以进行编译了

npm run build

image.png

出现这样的就是已经编译成功了。 检查下工作区的目录里面出现一个名为 dist的目录就是成功了, 这里可以使用 Live Server这个扩展插件来运行起来我们编译的index.html

image.png image.png image.png

点击后就会生成一个 5500端口的项目并且会自动打开index.html,点开控制台就可以看见

image.png

那就代表我们之前的操作一切ok

4. 接下来开始配置 css 打包

用到的插件有两个一个为 css-loadermini-css-extract-plugin

npm install mini-css-extract-plugin css-loader --save-dev

安装完毕后,我们再开始构建下 webpack.config.js

const { Configuration } = require("webpack");
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
/**
 * @type {Configuration} -- 使用 jsDoc 用来代码类型提示
 */
const config = {
  mode: "development", // 当前环境模式 development 开发模式
  entry: resolve(__dirname, "./src/index.js"), // 入口文件 利用 path模块里的 resolve 来进行绝对路径
  output: {
    path: resolve(__dirname, "./dist/"), // 输出配置 一般都会输出到 dist 目录下
    filename: "js/chunk-[contenthash].js", // 这样的意思是 js 文件都会放在 js目录下 并且使用 chunk + hash的方式进行命名
    clean: true, // 每次打包前会清除一下之前打包的旧文件防止重复
  },
  // 这些选项决定了如何处理项目中的不同类型的模块。
  module: {
    // rules 就是 webpack中所依赖的规则模块数组
    rules: [
      {
        test: /\.(css)$/, // 以 css 为结尾的文件会走此校验
        // use 的方式就是使用多个 loader
        use: [
          // 为每个包含 CSS 的 JS 文件创建一个 CSS 文件
          MiniCssExtractPlugin.loader,
          // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
          "css-loader",
        ],
      },
    ],
  },
  plugins: [
    // html 插件 用于帮我们把打包好的 js 文件自动注入到模板里
    new HtmlWebpackPlugin({
      filename: "index.html", // 打包后文件名称
      template: resolve(__dirname, "./public/index.html"), // 模板地址路径
      inject: "body", // js文件插入 body里
    }),
    new MiniCssExtractPlugin({
      filename: "styles/chunk-[contenthash].css", // 将css代码输出到 输出目录/styles文件夹下 也是以 chunk + hash的方式
      ignoreOrder: true, // 禁用 css order 警告
    }),
  ],
};

module.exports = config;

可以看出这次我们只添加了 module -> rules 部分 以及 上方引入 mini-css-extract-plugin 插件

然后我们从 src目录下新建一个css文件

image.png

style.css 内容为:

body{
    background-color: red;
}

并且 在 index.js 里引入 style.css - 内容是这样的:

import "./style.css";
console.log("哈哈哈,我是muddyrain,一个前端小🔥");

ok,然后我们就可以进行编译 npm run build 结果为这样子的那就没问题:

image.png image.png

然后还向上次一样在 index.hmtl文件上使用live-server进行运行-出来这样的结果那这一篇 css也已经构建完毕了.

image.png

5. 预编译 sass配置

这个css编译后 我们肯定会要在项目里使用 css预编译处理器来进行快速开发这里我们选择 sass-loader 这里需要安装的npm插件

npm install sass sass-loader --save-dev

webpack.config.js 配置:

const { Configuration } = require("webpack");
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
/**
 * @type {Configuration} -- 使用 jsDoc 用来代码类型提示
 */
const config = {
  mode: "development", // 当前环境模式 development 开发模式
  entry: resolve(__dirname, "./src/index.js"), // 入口文件 利用 path模块里的 resolve 来进行绝对路径
  output: {
    path: resolve(__dirname, "./dist/"), // 输出配置 一般都会输出到 dist 目录下
    filename: "js/chunk-[contenthash].js", // 这样的意思是 js 文件都会放在 js目录下 并且使用 chunk + hash的方式进行命名
    clean: true, // 每次打包前会清除一下之前打包的旧文件防止重复
  },
  // 这些选项决定了如何处理项目中的不同类型的模块。
  module: {
    // rules 就是 webpack中所依赖的规则模块数组
    rules: [
      {
        test: /\.(css|scss)$/, // 以 css 或者 scss 为结尾的文件会走此校验
        // use 的方式就是使用多个 loader
        use: [
          // 为每个包含 CSS 的 JS 文件创建一个 CSS 文件
          MiniCssExtractPlugin.loader,
          // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
          "css-loader",
          // 加载 Sass/SCSS 文件并将他们编译为 CSS。
          "sass-loader",
        ],
      },
    ],
  },
  plugins: [
    // html 插件 用于帮我们把打包好的 js 文件自动注入到模板里
    new HtmlWebpackPlugin({
      filename: "index.html", // 打包后文件名称
      template: resolve(__dirname, "./public/index.html"), // 模板地址路径
      inject: "body", // js文件插入 body里
    }),
    new MiniCssExtractPlugin({
      filename: "styles/chunk-[contenthash].css", // 将css代码输出到 输出目录/styles文件夹下 也是以 chunk + hash的方式
      ignoreOrder: true, // 禁用 css order 警告
    }),
  ],
};

module.exports = config;

这次在 module -> rules 里把 css-loader 改为可以俩种类型都支持的规则

编辑好配置就可以把之前写的 style.css 改为 style.scss了 并且在 index.js 里修改下之前引入的路径 和 style.scss改为 蓝色背景

image.png

style.scss 内容:

body{
    background-color: blue;
}

index.js 内容:

import "./style.scss";
console.log("哈哈哈,我是muddyrain,一个前端小🔥");

然后 我们在继续 npm run build 一次。

终端编译结果是这样的就可以了

image.png

yes,是不是很喜欢这样没有一点红色报错,successfully 成功的感觉!

dist 目录和上次几乎差不多但是内部文件类型的编译是 scss-loader 已经帮我们做了

image.png

再次使用 live-server 进行运行查看下

image.png

嗯,结果是预想的结果背景也是 蓝色(blue)了!

6. 编译 image 资源

因为已经查询到了 webpack5 不支持 url-loader ,那我们采用 assets 方案 -> webpack官网静态资源模块

下面我们配置下 webpack.config.js 配置:

const { Configuration } = require("webpack");
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
/**
 * @type {Configuration} -- 使用 jsDoc 用来代码类型提示
 */
const config = {
  mode: "development", // 当前环境模式 development 开发模式
  entry: resolve(__dirname, "./src/index.js"), // 入口文件 利用 path模块里的 resolve 来进行绝对路径
  output: {
    path: resolve(__dirname, "./dist/"), // 输出配置 一般都会输出到 dist 目录下
    filename: "js/chunk-[contenthash].js", // 这样的意思是 js 文件都会放在 js目录下 并且使用 chunk + hash的方式进行命名
    clean: true, // 每次打包前会清除一下之前打包的旧文件防止重复
  },
  // 这些选项决定了如何处理项目中的不同类型的模块。
  module: {
    // rules 就是 webpack中所依赖的规则模块数组
    rules: [
      {
        test: /\.(css|scss)$/, // 以 css 或者 scss 为结尾的文件会走此校验
        // use 的方式就是使用多个 loader
        use: [
          // 为每个包含 CSS 的 JS 文件创建一个 CSS 文件
          MiniCssExtractPlugin.loader,
          // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
          "css-loader",
          // 加载 Sass/SCSS 文件并将他们编译为 CSS。
          "sass-loader",
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg|webp)$/, // 匹配找一些后缀的文件
        type: "asset", // 类型为 静态资源
        parser: {
          // 转base64的条件
          dataUrlCondition: {
            maxSize: 100 * 1024, // 100kb  这个从 b开始计算的 所以需要 相乘计算下
          },
        },
        generator: {
          // 打包到 dist/image 文件下
          filename: "images/[contenthash][ext][query]",
        },
      },
    ],
  },
  plugins: [
    // html 插件 用于帮我们把打包好的 js 文件自动注入到模板里
    new HtmlWebpackPlugin({
      filename: "index.html", // 打包后文件名称
      template: resolve(__dirname, "./public/index.html"), // 模板地址路径
      inject: "body", // js文件插入 body里
    }),
    new MiniCssExtractPlugin({
      filename: "styles/chunk-[contenthash].css", // 将css代码输出到 输出目录/styles文件夹下 也是以 chunk + hash的方式
      ignoreOrder: true, // 禁用 css order 警告
    }),
  ],
};

module.exports = config;

配置好后 在 style.scss 中添加背景图片

image.png

style.scss 内容:

body {
  background-image: url("./1.jpg");
}

下面这个就是我用的图片 可能掘金会压缩 稍后我会在 github上进行发布下可以下载到源文件

1.jpg

图片文件大小为 50kb 以上

image.png

在我们正常的流程 文件最大为 100kb

根据上面的配置项我们接下来进行编译一下 npm run build

image.png

结果为这样的 我们的图片哪里去了呢?

仔细看下这段配置 - 符合 baseurl 条件 我们的图片才 57kb 这边设置的最大为 100kb

image.png

来运行下 -> dist/index.html 看下

image.png

css -> body 选择器的图片背景地址为 base64 格式的那就证明我们已经编译好了。

接下来我们 改下配置 把 baseurl 的条件换为 50kb 最大

{
    test: /\.(png|jpe?g|gif|svg|webp)$/, // 匹配找一些后缀的文件
    type: "asset", // 类型为 静态资源
    parser: {
      // 转base64的条件
      dataUrlCondition: {
        maxSize: 50 * 1024, // 50kb  这个从 b开始计算的 所以需要 相乘计算下
      },
    },
    generator: {
      // 打包到 dist/image 文件下
      filename: "images/[contenthash][ext][query]",
    },
},

然后 再编译下 webpack

image.png

dist/ 目录下 出现了 images 文件夹证明之前的条件是成功的 图片资源管理这边也已经完成咯~

7. 配置 babel

Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。babel中文网

官方说法是这样的意思, 就是 高级语法转成浏览器可以兼容的工具

需要加载的插件有:

npm install @babel/core babel-loader @babel/preset-env @babel/plugin-transform-runtime --save-dev
  • babel-loader -> babel需要加载编译的 loader
  • @babel/core -> babel核心依赖项 把它理解成 跟 js-core 一样吧 我是这么理解的 有问题希望大佬指明
  • @babel/preset-env -> 官方解释翻译下来是这样的 是一个智能预设,它允许您使用最新的 JavaScript,而无需微观管理目标环境需要哪些语法转换(以及可选的浏览器 polyfill)。 这既让你的生活更轻松,也让 JavaScript 包更小!
  • @babel/plugin-transform-runtime -> 一个插件,可以重用 Babel 的注入帮助代码以节省代码大小。

接下来我们再配置下 webpack.config.js:

const { Configuration } = require("webpack");
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
/**
 * @type {Configuration} -- 使用 jsDoc 用来代码类型提示
 */
const config = {
  mode: "development", // 当前环境模式 development 开发模式
  entry: resolve(__dirname, "./src/index.js"), // 入口文件 利用 path模块里的 resolve 来进行绝对路径
  output: {
    path: resolve(__dirname, "./dist/"), // 输出配置 一般都会输出到 dist 目录下
    filename: "js/chunk-[contenthash].js", // 这样的意思是 js 文件都会放在 js目录下 并且使用 chunk + hash的方式进行命名
    clean: true, // 每次打包前会清除一下之前打包的旧文件防止重复
  },
  // 这些选项决定了如何处理项目中的不同类型的模块。
  module: {
    // rules 就是 webpack中所依赖的规则模块数组
    rules: [
      {
        test: /\.(css|scss)$/, // 以 css 或者 scss 为结尾的文件会走此校验
        // use 的方式就是使用多个 loader
        use: [
          // 为每个包含 CSS 的 JS 文件创建一个 CSS 文件
          MiniCssExtractPlugin.loader,
          // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
          "css-loader",
          // 加载 Sass/SCSS 文件并将他们编译为 CSS。
          "sass-loader",
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg|webp)$/, // 匹配找一些后缀的文件
        type: "asset", // 类型为 静态资源
        parser: {
          // 转base64的条件
          dataUrlCondition: {
            maxSize: 50 * 1024, // 50kb  这个从 b开始计算的 所以需要 相乘计算下
          },
        },
        generator: {
          // 打包到 dist/image 文件下
          filename: "images/[contenthash][ext][query]",
        },
      },
      {
        test: /\.js$/, // 匹配js后缀文件
        exclude: /node_modules/, // 除了 node_modules 以外目录
        loader: "babel-loader", // 使用的 loader
      },
    ],
  },
  plugins: [
    // html 插件 用于帮我们把打包好的 js 文件自动注入到模板里
    new HtmlWebpackPlugin({
      filename: "index.html", // 打包后文件名称
      template: resolve(__dirname, "./public/index.html"), // 模板地址路径
      inject: "body", // js文件插入 body里
    }),
    new MiniCssExtractPlugin({
      filename: "styles/chunk-[contenthash].css", // 将css代码输出到 输出目录/styles文件夹下 也是以 chunk + hash的方式
      ignoreOrder: true, // 禁用 css order 警告
    }),
  ],
};

module.exports = config;

没有什么基本大体变化 -> 只是在 module->rules里添加了一条规则 5行代码

{
    test: /\.js$/, // 匹配js后缀文件
    exclude: /node_modules/, // 除了 node_modules 以外目录
    loader: "babel-loader", // 使用的 loader
},

配置好 webpack后我们再从工作区项目根目录里添加一个新文件 -> .babelrc文件

image.png

{
  "presets": [
    // 配置规则
    "@babel/preset-env"
  ],
  // 配置插件
  "plugins": ["@babel/plugin-transform-runtime"]
}

这个配置就是 babel需要的配置项 第一个就是 需要的 预设 和 需要的 集成

配置完再来改下 index.js

import "./style.scss";
console.log("哈哈哈,我是muddyrain,一个前端小🔥");
const a = "我是 小A";
console.log("快来打印我", a);

这里可以看到我们使用了 es6 的常量,然后我们再编译下试试

这里打开了 dist/js/chunk.xxxxxx.js 文件,编译并没有查询到有关 const 的单词

image.png

8. 配置 vue

这一篇就是我们重中之重了-配置常用的 vue 这里我配置的是 vue3的版本

需要的配置依赖有 :

npm install vue vue-loader vue-template-compiler @vue/compiler-sfc @vue/babel-preset-jsx --save-dev
  • vue -> 这个大家肯定知道 是结构配置完用来写 vue的
  • vue-loader -> 匹配vue文件来编译 template style script 里的文件把它编译成js
  • vue-template-compiler -> vue 模板编译成 虚拟-dom
  • @vue/compiler-sfc -> 文件三大要素是template、script、style,vue-compiler-sfc就是负责解析这三大要素
  • @vue/babel-preset-jsx -> 顾名思义了就是babel用来预设用的 如果想在 vue中使用 jsx ,我个人挺喜欢这个插件的

安装完毕后 来配置 webpack.config.js

const { Configuration } = require("webpack");
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { VueLoaderPlugin } = require('vue-loader')
/**
 * @type {Configuration} -- 使用 jsDoc 用来代码类型提示
 */
const config = {
  mode: "development", // 当前环境模式 development 开发模式
  entry: resolve(__dirname, "./src/index.js"), // 入口文件 利用 path模块里的 resolve 来进行绝对路径
  output: {
    path: resolve(__dirname, "./dist/"), // 输出配置 一般都会输出到 dist 目录下
    filename: "js/chunk-[contenthash].js", // 这样的意思是 js 文件都会放在 js目录下 并且使用 chunk + hash的方式进行命名
    clean: true, // 每次打包前会清除一下之前打包的旧文件防止重复
  },
  // 这些选项决定了如何处理项目中的不同类型的模块。
  module: {
    // rules 就是 webpack中所依赖的规则模块数组
    rules: [
      {
        test: /\.(css|scss)$/, // 以 css 或者 scss 为结尾的文件会走此校验
        // use 的方式就是使用多个 loader
        use: [
          // 为每个包含 CSS 的 JS 文件创建一个 CSS 文件
          MiniCssExtractPlugin.loader,
          // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
          "css-loader",
          // 加载 Sass/SCSS 文件并将他们编译为 CSS。
          "sass-loader",
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg|webp)$/, // 匹配找一些后缀的文件
        type: "asset", // 类型为 静态资源
        parser: {
          // 转base64的条件
          dataUrlCondition: {
            maxSize: 50 * 1024, // 50kb  这个从 b开始计算的 所以需要 相乘计算下
          },
        },
        generator: {
          // 打包到 dist/image 文件下
          filename: "images/[contenthash][ext][query]",
        },
      },
      {
        test: /\.js$/, // 匹配js后缀文件
        exclude: /node_modules/, // 除了 node_modules 以外目录
        loader: "babel-loader", // 使用的 loader
      },
      {
        test: /\.vue$/,
        loader: "vue-loader",
      },
    ],
  },
  plugins: [
    // html 插件 用于帮我们把打包好的 js 文件自动注入到模板里
    new HtmlWebpackPlugin({
      filename: "index.html", // 打包后文件名称
      template: resolve(__dirname, "./public/index.html"), // 模板地址路径
      inject: "body", // js文件插入 body里
    }),
    new MiniCssExtractPlugin({
      filename: "styles/chunk-[contenthash].css", // 将css代码输出到 输出目录/styles文件夹下 也是以 chunk + hash的方式
      ignoreOrder: true, // 禁用 css order 警告
    }),
    // 配置 vue编译的插件
    new VueLoaderPlugin()
  ],
};

module.exports = config;

配置好这些后 我们可以来操作文件了.

先把之前写的 style.scss 文件的内容剪切复制并把它删除, 在 src/ 目录下创建一个 App.vue 文件


<script setup>
import { ref } from "vue";

const msg = ref("我是message -> 我来自 vue的ref");
</script>

<template>
  {{ msg }}
</template>

<style lang="scss">
body {
  background-image: url("./1.jpg");
}
</style>

一个标准的 vue3的写法文件,另外把刚才复制的 scss 样式粘贴到 style 标签里

把之前写的 index.js 里的内容全部删除改为:

import { createApp } from "vue";
import App from "./App.vue";

createApp(App).mount("#app");

这个挂载是 我们之前在 public/index.html 里写了个 <div id="app"></div>

写好这些 我们开始运行 npm run build 一下

image.png

结果也出来了 里面内容也是我们在 vue 中写的。

9. 配置本地开发

接下来我们配置下本地开发 dev-server

const { resolve } = require("path");
const { Configuration } = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { VueLoaderPlugin } = require("vue-loader");
/**
 * @type {Configuration} -- 使用 jsDoc 用来代码类型提示
 */
const config = {
  mode: "development", // 当前环境模式 development 开发模式
  entry: resolve(__dirname, "./src/index.js"), // 入口文件 利用 path模块里的 resolve 来进行绝对路径
  output: {
    path: resolve(__dirname, "./dist/"), // 输出配置 一般都会输出到 dist 目录下
    filename: "js/chunk-[contenthash].js", // 这样的意思是 js 文件都会放在 js目录下 并且使用 chunk + hash的方式进行命名
    clean: true, // 每次打包前会清除一下之前打包的旧文件防止重复
  },
  // 开发服务器
  devServer: {
    static: {
      // 静态内存资源
      directory: resolve(__dirname, "../dist"),
    },
    // 开启 gzip 压缩
    compress: true,
    // 服务器 端口 9000
    port: 9000,
    // 热更新
    hot: true,
  },
  // 这些选项决定了如何处理项目中的不同类型的模块。
  module: {
    // rules 就是 webpack中所依赖的规则模块数组
    rules: [
      {
        test: /\.(css|scss)$/, // 以 css 或者 scss 为结尾的文件会走此校验
        // use 的方式就是使用多个 loader
        use: [
          // 为每个包含 CSS 的 JS 文件创建一个 CSS 文件
          MiniCssExtractPlugin.loader,
          // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
          "css-loader",
          // 加载 Sass/SCSS 文件并将他们编译为 CSS。
          "sass-loader",
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg|webp)$/, // 匹配找一些后缀的文件
        type: "asset", // 类型为 静态资源
        parser: {
          // 转base64的条件
          dataUrlCondition: {
            maxSize: 50 * 1024, // 50kb  这个从 b开始计算的 所以需要 相乘计算下
          },
        },
        generator: {
          // 打包到 dist/image 文件下
          filename: "images/[contenthash][ext][query]",
        },
      },
      {
        test: /\.js$/, // 匹配js后缀文件
        exclude: /node_modules/, // 除了 node_modules 以外目录
        loader: "babel-loader", // 使用的 loader
      },
      {
        test: /\.vue$/,
        loader: "vue-loader",
      },
    ],
  },
  plugins: [
    // html 插件 用于帮我们把打包好的 js 文件自动注入到模板里
    new HtmlWebpackPlugin({
      filename: "index.html", // 打包后文件名称
      template: resolve(__dirname, "./public/index.html"), // 模板地址路径
      inject: "body", // js文件插入 body里
    }),
    new MiniCssExtractPlugin({
      filename: "styles/chunk-[contenthash].css", // 将css代码输出到 输出目录/styles文件夹下 也是以 chunk + hash的方式
      ignoreOrder: true, // 禁用 css order 警告
    }),
    // 配置 vue编译的插件
    new VueLoaderPlugin(),
  ],
};

module.exports = config;

本次添加的代码:

// 开发服务器
devServer: {
    static: {
      // 静态内存资源
      directory: resolve(__dirname, "../dist"),
    },
    // 开启 gzip 压缩
    compress: true,
    // 服务器 端口 9000
    port: 9000,
    // 热更新
    hot: true,
},

配置好 devServer 后 我们开始配置下 package.json

"scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server"
},

然后 运行 npm run dev

image.png

出现这样的结果那就是 我们的 vue3 脚手架环境配置ok 了

下面是我此项目的 package.json 包 防止版本问题运行不起来

{
  "name": "muddyrain-vue-cli",
  "version": "1.0.0",
  "description": "自定义脚手架工具",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server"
  },
  "keywords": [
    "cli",
    "webpack"
  ],
  "author": "muddyrain",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.18.10",
    "@babel/plugin-transform-runtime": "^7.18.10",
    "@babel/preset-env": "^7.18.10",
    "@vue/babel-preset-jsx": "^1.3.1",
    "@vue/compiler-sfc": "^3.2.37",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "html-webpack-plugin": "^5.5.0",
    "i": "^0.3.7",
    "mini-css-extract-plugin": "^2.6.1",
    "npm": "^8.15.1",
    "sass": "^1.54.0",
    "sass-loader": "^13.0.2",
    "vue": "^3.2.37",
    "vue-loader": "^17.0.0",
    "vue-template-compiler": "^2.7.8",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.3"
  }
}

另外安利大家几个我个人认为开发vue/react比较好用的 vscode 插件

  • Vue Language Features (Volar) -> vue3 语言插件高亮以及智能语法提示 image.png
  • Auto Import -> 自动导入esMoudle image.png
  • Image preview -> 图片预览 image.png
  • IntelliSense for CSS class names in HTML -> 在 vue-template/jsx 样式类名提示 5crMfTj.gif
  • Material Icon Theme -> 文件主题图标 image.png
  • Path Intellisense -> 路径提示 image.png
  • Import Cost -> 显示导入的插件的文件大小 image.png

GitHub地址 -> muddyrain-vue-cli

最后感谢大家的阅读,希望大家多多支持,有问题多多交流。

3D2F3177.jpg