webpack5 + vue + tsx 项目构建

1,818 阅读3分钟

webpack5 + vue + tsx 项目构建

1、初始化项目并安装VUE3

npm init
yarn add vue

2、webpack套装

yarn add  webpack webpack-cli webpack-dev-server webpack-merge -D

3、新建文件夹和文件

..
-build
	-webpack.base.js	//基础配置,公用部分
	-webpack.prod.js	//发布环境配置
	-webpack.dev.js	//生产环境配置
-/build
-/src
	-index.tsx	//入口文件
	shims-vue.d.ts //解决 vue 类型报错
-src
-dist	//发布文件夹
-/dist
-index.html //模板
..

index.html模板书写

<!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>VUE3&TSX</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

shims-vue.d.ts配置

declare module "*.vue" {
  import type { DefineComponent } from "vue";
  const component: DefineComponent<{}, {}, any>;
  export default component;
}

declare module "*.svg" {
  const centent: string;
  export default centent;
}


4、配置webpack

1)webpack.base.js配置入口

yarn add html-webpack-plugin css-loader less-loader text-loader file-loader thread-loader mini-css-extract-plugin -D
yarn add vue-loader@next @vue/compiler-sfc @babel/preset-env @vue/cli-plugin-babel @babel/preset-typescript babel-loader @babel/core -D
yarn add typescript
//webpack.base.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
const resolve = (dir) => path.resolve(__dirname, dir);
module.exports = {
  entry: "./src/main.ts", //配置入口文件
  plugins: [
    new HtmlWebpackPlugin({
      //生成入口HTML文件
      template: "./index.html",
      filename: "index.html",
    }),
    new MiniCssExtractPlugin({
      //提取css到单独的文件中
      filename: "[name].css",
      chunkFilename: "css/chunk.[name].css",
      ignoreOrder: true,
    }),
  ],
  module: {
    rules: [
      //处理css 文件
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
      //处理less文件
      {
        test: /\.less$/,
        use: [MiniCssExtractPlugin.loader, "less-loader", "css-loader"],
      },
      //处理vue文件
      {
        test: /\.vue$/,
        use: [
          {
            loader: "vue-loader",
            options: {
              cssModules: {
                localIdentName: "[path][name]---[local]---[hash:base64:5]",
                camelCase: true,
              },
            },
          },
        ],
      },
      //处理ts,tsx,js文件
      {
        test: /\.(js|ts|tsx)$/,
        exclude:
          /(node_modules|scripts[\\/]libs|geojson[\\/]new|share[\\/]libs|scripts\\i18n\\index)/,
        use: [
          "thread-loader",
          {
            loader: "babel-loader",
            options: {
              rootMode: "upward",
              cacheDirectory: true,
            },
          },
        ],
      },
      //处理html
      {
        test: /\.html$/,
        use: [{ loader: "text-loader" }],
      },
      //处理图片
      {
        test: /\.(png|jpe?g|gif|svg|ico)(\?.*)?$/i,
        use: [
          {
            loader: "url-loader",
            options: {
              name: "[path][name].[ext]",
              limit: 64,
              outputPath: "images",
            },
          },
        ],
      },
      //处理其他文件
      {
        test: /\.(woff2?|eot|ttf|otf|mtl|obj)(\?.*)?$/i,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[path][name].[ext]",
              outputPath: "font",
            },
          },
        ],
      },
    ],
  },
  resolve: {
    alias: {
      //别名配置
      "@": resolve("../src"),
      src: resolve("../src"),
      components: resolve("../src/components"),
      router: resolve("../src/router"),
      store: resolve("../src/store"),
      views: resolve("../src/views"),
      apis: resolve("../src/apis"),
    },
    extensions: [".tsx", ".ts", ".wasm", ".mjs", ".js", ".json"],
  },
};

2)配置babel

//babel.config.js
module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        targets: {
          browsers: ["last 1 version"],
        },
        exclude: ["transform-async-to-generator", "transform-regenerator"],
      },
    ],
    ["@vue/cli-plugin-babel/preset"],
    ["@babel/preset-typescript"],
  ],
};

3)配置开发环境

//webpack.dev.js
const common = require("./webpack.base");
const { merge } = require("webpack-merge");
module.exports = merge(common, {
  devtool: "inline-source-map", //控制台调试代码
  mode: "development", //开发环境webpack内置优化
  devServer: {
    client: {
      progress: true,
    },
    compress: true, //gzip压缩
    hot: true, //热更新
    // open: true, //自动打开默认浏览器
    open: {
      app: {
        name: "goole-chrome", //走动打开chrome
        arguments: ["--incognito", "--new-window"], //无痕,新的窗口
      },
    },
    port: 8081, //监听端口
    proxy: {}, //代理配置
  },
});

4)配置生产环境

//webpack.prod.js
const common = require("./webpack.base");
const { merge } = require("webpack-merge");
const path = require("path");

module.exports = merge(common, {
  mode: "production",
  output: {
    //出口
    path: path.resolve(__dirname, "../dist"), //输出路径
    clean: true, //清空打包文件
    filename: "js/[name].[chunkhash].js", //输出文件名
    chunkFilename: "js/[name].[chunkhash].js", //输出异步文件文件名
  },
});

5)配置启动命令

//package.json
{
...
"scripts": {
    "start": "npm run dev",
    "dev": "webpack-dev-server --hot --open --config build/webpack.dev.js",
    "build": "webpack --config build/webpack.prod.js"
  },
...
}

6)写一个demo src/app.tsx

import { defineComponent, ref } from "vue";

export default defineComponent({
  name: "App",
  setup() {
    const title = ref<string>("Hello VUE3&TSX!");
    const auther: string = "Code Wly";
    return () => (
      <>
        <div class="app">{title.value}</div>
        <div class="auth">auther:{auther}</div>
      </>
    );
  },
});

在src/main.ts 引入APP,并使用

import { createApp } from "vue";
import App from "./App";
const app = createApp(App);
app.mount("#app");

7)配置tsconfig.json文件

{
    "include": ["src"],
    "exclude": ["node_modules", "dist", "assets/"],
    "compilerOptions": {
        "jsx": "preserve",
        "jsxFactory": "h",
        "strictNullChecks": true,
        "allowJs": true,
        "moduleResolution": "node",
        "isolatedModules": false,
        "lib": ["dom", "es5", "es6", "es7", "es2015.promise"],
        "sourceMap": true,
        "pretty": true,
		"typeRoots": [
			"src/globalDeclare"
		],

        "target": "ES5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
        "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
        "checkJs": false /* Report errors in .js files. */,
        "downlevelIteration": true /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */,
        "strict": false /* Enable all strict type-checking options. */,
        "baseUrl": "./" /* Base directory to resolve non-absolute module names. */,
        "paths": {
            "@/*": ["src/*"],
            "src/*": ["src/*"],
            "apis/*": ["src/apis/*"],
            "components/*": ["src/components/*"],
            "config/*": ["src/config/*"],
            "hook/*": ["src/hook/*"],
            "router/*": ["src/router/*"],
            "store/*": ["src/store/*"],
            "theme/*": ["src/theme/*"],
            "util/*": ["src/util/*"],
            "views/*": ["src/views/*"],
        },
        "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
        "esModuleInterop": true,
        "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
        "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,
        "resolveJsonModule": true
    },
}

8)开发环境最后一步 在package.json中配置的命令

#终端输入
npm start
#或者
npm run dev

9)生产环境最后一步 在package.json中配置的命令

#终端输入
npm run build

END 建议

webpack 配置在webpack官网进行查阅使用。webpack.js.org/
typeScript 写法规范语法规则在typeScript官网查阅使用。www.tslang.cn/
vue jsx 写法规范在vue github 中 yyx 有详细说明。github.com/vuejs/babel…

Finish 2022-3-5 (最好不要复制粘贴,通过查阅文档加实验,理解每一步)