手写webpack去构建Vue3项目

185 阅读2分钟

新建基本的webpack结构

public文件(index.html)

src文件(assets文件夹、views文件夹、App.vue、main.ts)

webpack.config.js文件

npm init -y 创建package.json

tsc --init 创建tsconfig.json

安装webpack和webpack-cli,如果webpack 3以上则需要安装webpack-cli配套

yarn add webpack
yarn add webpack-cli

安装启动dev的环境 yarn add webpack-dev-server

安装webapck插件yarn add html-webpack-plugin

main.ts

import {createApp} from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

public下的index.html 加一个id

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

需要的依赖

{
    "name": "webpack-vue",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "webpack-dev-server",
        "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
        "@vue/compiler-sfc": "^3.2.38", //解析vue文件
        "clean-webpack-plugin": "^4.0.0", //打包 的时候清空dist
        "css-loader": "^6.7.1", //处理css文件
        "html-webpack-plugin": "^5.5.0", //html 模板
        "less": "^4.1.3",  //处理less
        "less-loader": "^11.0.0", //处理less文件
        "style-loader": "^3.3.1", //处理style样式
        "ts-loader": "^9.3.1", //处理ts
        "typescript": "^4.8.2", //ts
        "vue": "^3.2.38", //vue
        "vue-loader": "^17.0.0", //解析vue
        "webpack": "^5.74.0",
        "webpack-cli": "^4.10.0",
        "webpack-dev-server": "^4.10.0"//dev
    }
}

tsconfig.json配置

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

package.json增加dev和build命令

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server",
    "build": "webpack"
  },

配置webpage

const { Configuration } = require('webpack')
const path = require('path')//路径插件
const htmlWebpackPlugin = require('html-webpack-plugin')//html模板插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')//情空dist打包的插件
const { VueLoaderPlugin } = require('vue-loader/dist/index');//解析vue的插件

/**
 * @type {Configuration} //配置智能提示
 */
const config = {
    mode: "development",//选择打包模式
    entry: './src/main.ts', //入口文件
    output: {
        filename: "[hash].js",//生成一个哈希值作为文件名
        path: path.resolve(__dirname, 'dist') //出口文件,绝对路径下的dist文件夹
    },
    module: {  //模块处理规则
        rules: [
            {
                test: /\.vue$/, //遇到以.vue结尾的文件利用vue-loader处理,解析vue 模板
                use: "vue-loader"
            },
            {
                test: /\.less$/, //解析 less
                use: ["style-loader", "css-loader", "less-loader"],
            },
            {
                test: /\.css$/, //解析css
                use: ["style-loader", "css-loader"],
            },
            {
                test: /\.ts$/,  //解析ts
                loader: "ts-loader",
                options: {  //不能直接使用要针对单文件配置
                    configFile: path.resolve(process.cwd(), 'tsconfig.json'),
                    appendTsSuffixTo: [/\.vue$/]
                },
            }
        ]
    },
    plugins: [//插件
        new htmlWebpackPlugin({
            template: "./public/index.html" //html模板
        }),
        new CleanWebpackPlugin(), //打包清空dist
        new VueLoaderPlugin(), //解析vue
    ],
    resolve: {
        alias: {
            "@": path.resolve(__dirname, './src') // 别名
        },
        extensions: ['.js', '.json', '.vue', '.ts', '.tsx'] //自动识别后缀
    },
    stats:"errors-only", //取消提示
    devServer: {
        proxy: {},//代理
        port: 9001,//指定端口
        hot: true,//热更新
        open: true,//是否打开网页
    },
    externals: {
        vue: "Vue" //打包的时候不会把vue打进来,要在html用CDN 引入vue,用法键值 import xxx from 'vue',键值CDN名
    },
}
 
 
module.exports = config

配置vue 声明文件不然ts 识别不了vue 后缀
 
declare module "*.vue" {
    import { DefineComponent } from "vue"
    const component: DefineComponent<{}, {}, any>
    export default component
  }

参考

小满Vue3(第四十三章 webpack 从0到1 构建vue3)_哔哩哔哩_bilibili