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…