小满视频
- 很多解释使用通义灵码搜的,通义灵码的搜索结果也是有错误的
 - 全程使用pnpm包管理工具,和npm的用法基本一样
 
学习总结
 1. 多看看webpack官网
 2. webpack的作用:配置一堆东西,达到运行程序的目的
 3. 无论什么东西都转成js,然后插入到一个空空的html文件中运行
 4. webpack就是个管理者,管理着一堆loader,一堆loader的作用就是把自己负责的东西弄成js
 
手动搭建Vue项目,使用webpack4
- 手动构建webpack基本环境
 - 1. 初始化node项目
 - 2. 生成TypeScript项目
 - 3. 安装webpack
 - 4. 安装webpack-cli
 - 5. 安装webpack-dev-server
 - 6. 安装html-webpack-plugin
 - 7. 安装Vue
 - 8 安装vue-loader
 - 9 安装clean-webpack-plugin
 - 10. 结果
 - 小结:
 - 项目目录树
 - 各文件代码
 - 1. webpack.config.js
 - 2. tsconfi.json
 - 3. package.json
 - 4. main.ts
 - 5. end.d.ts
 - 6. App.vue
 - 7. /public/index.html
 
- webpack.config.js中的其他配置项
 - 1. resolve解析器
 - alias:设置别名
 - extensions:省略后缀名
 
- 2. plugin 插件
 - 3. devServer 网络/服务相关配置
 - 4. stats 控制台信息如何显示
 - 5. module.rules配置预加载器
 - 6. 外部扩展(Externals)
 
手动构建webpack基本环境
webpack官网链接
1. 初始化node项目
- 初始化一个 Node.js 项目,并生成一个 package.json 文件
 
pnpm init
 
执行命令后自动创建package.json文件,内容如下:
{
  "name": "webpack-demo", 项目的名称
  "version": "1.0.0",项目的版本号
  "description": "",项目的简短描述
  "main": "index.js",项目的主入口文件
  "scripts": {项目的脚本命令,如测试脚本。
    "test": "echo \"Error: no test specified\" && exit 1"定义了一个简单的测试命令,当运行 npm test 时,会输出错误信息并退出。
  },
  "keywords": [],项目的关键词列表,用于搜索和分类
  "author": "",项目的作者信息
  "license": "ISC"项目的许可类型
}
 
2. 生成TypeScript项目
- 安装typescript
 
pnpm i typescript -g
 
- 生成 TypeScript 项目,和项目的初始配置文件 tsconfig.json
 
tsc --init
 
- tsconfig.json内容
 
{
  "compilerOptions": {
  	  target: es2016  设置目标 ECMAScript 版本
	  module: commonjs 指定模块系统。这里的 "commonjs" 表示使用 CommonJS 模块系统。
	  strict: true 启用所有严格的类型检查选项
	  esModuleInterop: true 启用 ES 模块与 CommonJS 模块之间的互操作性。这里的 true 表示启用此功能。
	  skipLibCheck: true 是否跳过类型声明文件的检查。这里的 true 表示跳过类型声明文件的检查。
	  forceConsistentCasingInFileNames: true 强制要求文件名大小写一致。这里的 true 表示启用此功能。
  }
}
 
-查看全局安装的插件的安装位置
npm config get prefix
 
3. 安装webpack
webpack官网
-  
webpack.config.js文件中所有的配置项都是webpack管理的 -  
安装webpack
 
pnpm add webpack -D
 
- Webpack 是一个非常流行的 JavaScript 模块打包器,用于将现代前端应用中的各种资源(如 JavaScript、CSS、图片等)打包成一个或多个浏览器可以加载的文件。Webpack 提供了一种强大的方式来组织和管理前端资源,使其易于维护和优化。
 - 根目录创建
webpack.config.js文件 webpack.config.js中配置打包的入口和出口文件及打包后文件的路径
const config = {
    mode: 'development', // 开发模式
    entry: "./src/main.ts", // 入口文件
    output: {
        filename: "[fullhash].js", // 输出文件名
        path: path.resolve(__dirname , "dist") // 输出路径
    },
}
module.exports = config;
 
__dirname: 表示当前配置文件所在的目录。
‘dist’: 表示输出文件所在的子目录名。
path.resolve: 用于将相对路径转换为绝对路径。
4. 安装webpack-cli
pnpm add webpack-cli -D
 
- 在
package.json文件中配置打包命令 
  "scripts": {
    "bulid": "webpack",
	...
	...
  },
 
-  
webpack-cli 是 Webpack 提供的命令行工具,用于在命令行中执行 Webpack 相关的操作。webpack-cli 主要完成以下几项工作:
- 解析和处理命令行参数:webpack-cli 负责解析用户在命令行中输入的参数,包括配置文件路径、打包模式、插件等信息。通过解析这些参数,webpack-cli 确定如何执行 Webpack 相关的操作。
 - 载入并执行 Webpack 配置:webpack-cli 负责读取并解析指定的 Webpack 配置文件(通常是 webpack.config.js)。通过读取配置文件,webpack-cli 知道如何进行模块打包、资源处理等操作。
 - 调用 Webpack API:通过调用 Webpack 提供的 API,webpack-cli 将用户输入的参数和配置转化为具体的 Webpack 打包操作。webpack-cli 可以执行 Webpack 的构建、开发服务器启动、打包分析等功能。
 - 提供辅助功能:除了执行 Webpack 操作外,webpack-cli 还提供了一些辅助功能,比如生成 Webpack 相关的配置文件模板、帮助命令、插件等,帮助开发者更方便地使用 Webpack。
 
 -  
在命令行输入:
pnpm run dev、pnpm run build时,通过webpack-cli执行webpack中的命令,并使用相应的配置,比如:webpack.config.js中打包的入口和出口等配置项 -  
不安装此插件也可以运行webpack,只不过可能需要很多复杂的命令
 
5. 安装webpack-dev-server
- 作用:
webpack-dev-server 是一个基于 Node.js 的本地开发服务器,它可以与 Webpack 一起使用,为开发者提供实时重新加载和热模块替换等功能。它能够自动监听文件更改,并在文件发生变化时重新编译并刷新浏览器,从而极大地提高了开发效率。 
pnpm add webpack-dev-server -D
 
6. 安装html-webpack-plugin
- 作用:
用于生成 HTML 文件,并自动注入 Webpack 打包后的 JavaScript 和 CSS 文件。这个插件可以帮助你轻松地管理和自动化 HTML 文件的生成过程,确保每次构建后都能得到最新的 HTML 文件。 
pnpm add html-webpack-plugin -D
 
- 在
package.json文件中配置运行命令 
  "scripts": {
    "dev":"webpack-dev-server --open",
	...
	...
  },
 
–open:自动打开浏览器
- 在webpack.config.js中配置此插件:
 
// 导入html-webpack-plugin
const HtmlWebpackPlugin = require("html-webpack-plugin");
 
    plugins: [
        new HtmlWebpackPlugin({
          template: './public/index.html', // 指定模板文件
          filename: 'index.html',        // 输出文件名
          inject: 'body'                 // 注入的位置
        })
      ],
 
7. 安装Vue
pnpm add vue -D
 
main.ts
import { createApp } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");
 
- App.vue
 
<template>
  <div>
      test
  </div>
</template>
<script setup lang=ts>
    
</script>
<style scoped lang="scss" >
</style>
 
- 新建
vue.d.ts文件,main.ts中使用了import App from "./App.vue";代码,在编译时TypeScript不认识.vue文件,在此声明.vue文件的类型 
declare module "*.vue"{
    import type {DefineComponent} from 'vue'
    const component:DefineComponent<{},{},any>
    export default component
}
 
.d.ts文件是 TypeScript 定义文件的一种。在 TypeScript 中,.d.ts 文件用于提供类型定义,以便 TypeScript 编译器可以理解未包含类型信息的 JavaScript 代码或其他 TypeScript 模块的类型。在编译时TypeScript 编译器会在项目的根目录及其子目录中查找 .d.ts 文件。declare module:用于声明一个模块的类型定义- declare module “*.vue”: 声明一个模块,该模块匹配所有的 .vue 文件。
 - import type {DefineComponent} from ‘vue’: 导入 DefineComponent 类型,这是 Vue.js 中的一个类型,用于表示 Vue 组件。
 - const component: DefineComponent<{},{},any>: 定义一个名为 component 的常量,它的类型为 DefineComponent。这里的泛型参数分别代表: 
    
- 第一个参数 {} 表示组件的 props 类型为空。
 - 第二个参数 {} 表示组件的 emits 类型为空。
 - 第三个参数 any 表示组件的 data 类型为 any。
 
 
此时pnpm build打包时会报错:
ERROR in ./src/App.vue 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <template>
| <div>
| test
@ ./src/main.ts 2:0-28 4:10-13
翻译:您可能需要一个适当的加载器来处理此文件类型,目前没有配置加载器来处理该文件。请参阅https://webpack.js.org/concepts#loaders
- 打包工具webpack不认识<template>等代码,需要一个新的工具
vue-loader 
8 安装vue-loader
vue-loader官网
- 安装
vue-loader 
pnpm add vue-loader -D
 
- 在
webpack.config.js中配置vue-loader 
// 导入vue-loader
const { VueLoaderPlugin } = require("vue-loader");
const config = { // 执行命令npm run build,按照config中的配置打包文件
	...
    module: {
        rules: [
          // 以.vue结尾的文件,指定vue-loader加载器来处理
          {
            test: /\.vue$/,
            loader: 'vue-loader'
          },
        ]
      },
    plugins: [
		...
        // 引入vue-loader插件
        new VueLoaderPlugin(),
      ],
}
 
-  
作用:
vue Loader是一个webpack的loader(加载器),它允许你以一种名为单文件组件 (SFCs)的格式撰写 Vue 组件 -  
vue-loader部分工作流程:- 调用
@vue/compiler-sfc会解析文件,提取每个语言块, - 通过标签中
lang="ts"或lang="scss"中lang的特性以及 webpack 配置中的规则自动推断出要使用的预处理(loader) vue-loader调用ts-loader预处理器,处理<script>部分;调用scss-loader预处理器,处理<style>部分- 最后将他们组装成一个 ES Module,它的默认导出是一个 Vue.js 组件选项的对象。
 
 - 调用
 -  
Vue 单文件组件 (SFC) 规范:官网介绍
vue 文件是一个自定义的文件类型,用类 HTML 语法描述一个 Vue 组件。每个 .vue 文件包含三种类型的顶级语言块 <template>、<script> 和 <style>,还允许添加可选的自定义块 -  
vue-loader官网介绍说需要安装
vue-template-compiler,在vue3中已经包含了相同功能的@vue/compiler-sfc插件,已经不需要再安装

 
9 安装clean-webpack-plugin
- 安装clean-webpack-plugin
 
pnpm add clean-webpack-plugin -D
 
-  
作用:用于在构建之前(
pnpm build)清理输出目录(dist)。这个插件可以帮助你在每次构建时删除旧的构建文件,确保输出目录只包含最新构建的结果。这对于避免旧文件残留、减少混淆等问题非常有用。 -  
webpack.config.js 
// 导入clean-webpack-plugin
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
 
    plugins: [
		...
        // 引入clean-webpack-plugin
        new CleanWebpackPlugin()
      ],
}
 
10. 结果
- 在浏览器中正常执行
 
pnpm dev
 
- 打包后,打开
/dist/html文件,执行正常 
 pnpm build
 
小结:
项目目录树

各文件代码
1. webpack.config.js
// 导入Configuration,使用注解的方式提供书写代码的智能提示
const {Configuration} = require("webpack");
// 导入vue-loader
const { VueLoaderPlugin } = require("vue-loader");
// 导入html-webpack-plugin
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 导入clean-webpack-plugin
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const path = require("path");
/**
 * @type {Configuration}
 */
const config = { // 执行命令npm run build,按照config中的配置打包文件
    mode: 'development', // 开发模式
    entry: "./src/main.ts", // 入口文件
    module: {
        rules: [
          // 以.vue结尾的文件,指定使用vue-loader加载器来处理
          {
            test: /\.vue$/,
            loader: 'vue-loader'
          },
        ]
      },
    output: {
        filename: "[fullhash].js", // 输出文件名
        path: path.resolve(__dirname , "dist") // 输出路径
    },
    // resolve: {
    //     extensions: ['.tsx', '.ts', '.js'] // 自动解析扩展名
    // },
    plugins: [
        new HtmlWebpackPlugin({
          template: './public/index.html', // 指定模板文件
          filename: 'index.html',        // 输出文件名
          inject: 'body'                 // 注入的位置
        }),
        // 引入vue-loader插件
        new VueLoaderPlugin(),
        // 引入clean-webpack-plugin
        new CleanWebpackPlugin()
      ],
}
module.exports = config;
 
2. tsconfi.json
{
  "compilerOptions": {
  	  target: es2016  
	  module: commonjs 
	  strict: true 
	  esModuleInterop: true 
	  skipLibCheck: true 
	  forceConsistentCasingInFileNames: true 
  }
}
 
3. package.json
{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server --open",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^4.0.0",
    "html-webpack-plugin": "^5.5.0",
    "ts-loader": "^9.5.1",
    "vue": "3.2.38",
    "vue-loader": "^17.4.2",
    "webpack": "^5.74.0",
    "webpack-cli": "^5.1.4",
    "webpack-dev-server": "^4.10.1"
  }
}
 
4. main.ts
import { createApp } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");
 
5. end.d.ts
declare module "*.vue"{
    import type {DefineComponent} from 'vue'
    const component:DefineComponent<{},{},any>
    export default component
}
 
6. App.vue
<template>
  <div>
      test
  </div>
</template>
<script setup lang="ts"></script>
<style scoped ></style>
 
7. /public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>webpack-demo</title>
</head>
<body>
    <div id="app"></div>
</body>
</html>
 
webpack.config.js中的其他配置项
    resolve: {
        alias: {
          '@': path.resolve(__dirname, 'src')
        },
        extensions: ['.tsx', '.ts', '.js'] // import 时,可以省略后缀名
    },
 
1. resolve解析器
官网详细说明
- 设置模块如何被解析
 - 使用import和require时的相关配置
 
alias:设置别名
- 设置@的别名
 
    resolve: {
        alias: {
          '@': path.resolve(__dirname, 'src')
        }
    },
 
__dirname是 Node.js 中的一个全局变量,用于表示当前文件所在的目录的绝对路径- 在
import或require语句中使用@时,相当于使用当前文件的路径/src 
extensions:省略后缀名
    resolve: {
        extensions: ['.tsx', '.ts', '.js'] // import 时,可以省略后缀名
    },
 
- 如需导入文件
/src/views/index.js,可以不写后缀import ex from “src/views/index” - 假如目录中有同名文件
/src/views/index.ts,按照extensions给定的顺序导入的是ts文件 
2. plugin 插件
作用: 各种方法修改webpack的构建过程,达到各种各样的目的
- 美化在构建过程中cmd中展示的各种信息
 
// 安装
pnpm add friendy-error-webpack-plugin -D
// 引入
const FriendlyErrorsWebpackPlugin = require("friendly-errors-webpack-plugin");
//使用
plugins: [
    // 引入friendly-errors-webpack-plugin
    new FriendlyErrorsWebpackPlugin({
      compilationSuccessInfo: {
        messages: [`You application is running here http://localhost:5173`],
      }
    }),
  ],
 
3. devServer 网络/服务相关配置
官网详细说明
- 配置启动后监听的端口号,通过
pnpm dev启动项目后,浏览器中端口号 
  devServer: {
    port: 5173, // 端口号
  },
 
4. stats 控制台信息如何显示
官网的详细说明
 作用: 控制台信息如何显示
- 只有在错误时展示信息
 
stats:"errors-only",
 
5. module.rules配置预加载器
官方的详细说明
-  
webpack原生只认识js和json文件,遇到其他类型文件时通过rules中配置规则,找对应的预加载器,把所有的文件都解析成
js -  
在
rules中有多少loader,就需要pnpm安装多少loader 
  module: {
    rules: [
      // 以.vue结尾的文件,指定使用vue-loader加载器来处理
      {
        test: /\.vue$/,
        use: "vue-loader",
      },
      // 以.css结尾的文件,指定使用css-loader和style-loader加载器来处理
      // use中的loader是倒序执行的,不能乱排顺序
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      // 以.ts结尾的文件,ts-loader加载器来处理
      // {
      //   test: /\.ts$/,
      //   use: [
      //     {
      //       loader: "ts-loader",
      //       options: {
      //         configFile: path.resolve(process.cwd(), "tsconfig.json"),
      //         appendTsSuffixTo: [/\.vue$/],
      //       },
      //     },
      //   ],
      // },
      {
        test: /\.ts$/,
        loader: "ts-loader",
        options: {
          configFile: path.resolve(process.cwd(), "tsconfig.json"),
          appendTsSuffixTo: [/\.vue$/],
        },
      },
    ],
  },
 
6. 外部扩展(Externals)
代码:
  externals: {
    vue: "Vue",
  },
 
- 使用上述代码后,打包的文件中将不包含vue,在运行打包文件index.html会报错

 - Vue给我们提供了CDN的引入方式:
 
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
 
将上述代码插入到指定的模板文件index.html中再打包就可以运行了.
- 优点:有效的减少打包后的体积,减少服务器的压力
 - 缺点:vue的相关文件都会从网络下载,会增加网络负担,如果网络传输速度不够快,直接影响使用者的体验
 



















