React + TS Loader
Step 1: 安装npm包
先装react依赖
npm i react react-dom --save
npm i @types/react @types/react-dom --save-dev
# yarn add react react-dom
# yarn add -D @types/react @types/react-dom
再装个ts-loader和awesome-typescript-loader
npm i ts-loader awesome-typescript-loader --save
# yarn add ts-loader awesome-typescript-loader
再装webpack开发用的
npm i webpack-dev-server html-webpack-plugin --save-dev
# yarn add webpack-dev-server html-webpack-plugin -D
注意:不装types会报错
- webpack-dev-server 用来启动一个网站
- html-webpack-plugin用于为react程序提供模板
Step 2: 编写一个React程序
ReactHello.tsx
import React from 'react'
import ReactDOM from 'react-dom'
const App : (() => JSX.Element) = () => {
return <div>
<h1>Hello React!</h1>
</div>
}
ReactDOM.render(<App />, document.getElementById('root'))
因为报错,需要考虑增加 `esModuleInterop:true`和`jsx` 到`tsconfig.json`
**esModuleInterop**: 让TypeScript分别对待CommonJS/AMD/UMD modules,从而让用户获得统一的体验。
jsx选项需要设置成react,这样typescript会将jsx语法转换为React.createClass。
tsconfig.json
{
"compilerOptions": {
"esModuleInterop": true ,
"jsx" : "react"
}
}
Step 3: 编写一个html模板文件
template.html
<html>
<head>
</head>
<body>
<div id="root"></div>
</body>
</html>
Step 4:编写对应的webpack文件
webpack.react.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry : {
index : './src/ReactHello.tsx'
},
mode : "development",
module : {
rules : [
{
test : /\.tsx?$/,
use : "ts-loader",
exclude : /node_modules/
},
]
},
resolve : {
extensions :['.tsx', '.ts', '.js']
},
output : {
filename : "bundle.[name].js",
path : path.resolve(__dirname, "dist")
},
devServer : {
contentBase : path.resolve(__dirname, "dist"),
port : 3020
},
plugins : [
new HtmlWebpackPlugin({
template : path.resolve(__dirname, "template.html")
})
]
}
Step 5: 增加package.json脚本
"start:react": "webpack serve --config ./webpack.react.js"
Step 6: 尝试执行脚本
npm run start:react
React + Babel Preset
babel-preset vs ts-loader的区别
- babel-loader(背后是:babel)
- babel是干什么的? —— The Compiler for next generation Javascript
- 所有编译JS的事情,babel都干!
- es6->es5->es3->polifill
- 缓存+优化
- 插件+生态
- ts-loader(背后是tsc)
- ts -> es
Step 1: 补充babel的依赖
npm i babel-loader @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript --save-dev
# yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript
preset 是一套 plugin 的集合
Step 2: 写一个单独的webpack文件
webpack.react.withbabel.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry : {
index : './src/ReactHello.tsx'
},
mode : "development",
module : {
rules : [
{
test : /\.tsx?$/,
use : {
loader : 'babel-loader',
options : {
presets : [
"@babel/preset-typescript",
"@babel/preset-react",
"@babel/preset-env"
]
}
},
exclude : /node_modules/
},
]
},
resolve : {
extensions :['.tsx', '.ts', '.js']
},
output : {
filename : "bundle.[name].js",
path : path.resolve(__dirname, "dist")
},
devServer : {
contentBase : path.resolve(__dirname, "dist"),
port : 3020
},
plugins : [
new HtmlWebpackPlugin({
template : path.resolve(__dirname, "template.html")
})
]
}
Step 3: 增加npm脚本
"start:react-babel": "webpack serve --config ./webpack.react.withbabel.js",
Step 4: 尝试一下
npm run start:react-babel
Vue(3.0) + loader
Step 1 : 增加vue需要的依赖
# Vue 的依赖
npm i vue@next --save
npm i -D @vue/compiler-sfc
# yarn add vue@next
# yarn add -D @vue/compiler-sfc
# Vue的loader
npm i vue-loader --save-dev
# yarn add vue-loader -D
sfc - Single File Component
Step 2 : 写一个Vue的SFC和一个bootstraper
Hello.vue
<template>
<h1>Hello Vue!</h1>
</template>
<script lang='ts'>
export default {
setup() {
return {
}
}
}
</script>
main.ts
import {createApp} from 'vue'
import Hello from './Hello.vue'
createApp(Hello).mount("#root")
写完但是Hello.vue报错,为啥?因为还需要一个shim文件:
shim(垫片),通常为了处理兼容而命名。这个shim的目标是让vscode和webpack等知道.vue的文件,可以当做一个组件定义文件来使用。
shims-vue.d.ts
/* eslint-disable */
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
Step 3: 写一个vue的webpack.config
webpack.vue.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {VueLoaderPlugin} = require('vue-loader')
module.exports = {
entry : {
index : './src/main.ts'
},
mode : "development",
module : {
rules : [
{
test : /\.tsx?$/,
loader : "ts-loader",
options : {
appendTsSuffixTo : [/\.vue$/],
},
exclude : /node_modules/
},
{
test : /\.vue$/,
loader : 'vue-loader'
}
]
},
resolve : {
extensions :['.tsx', '.ts', '.js']
},
output : {
filename : "bundle.[name].js",
path : path.resolve(__dirname, "dist")
},
devServer : {
contentBase : path.resolve(__dirname, "dist"),
port : 3020
},
plugins : [
new HtmlWebpackPlugin({
template : path.resolve(__dirname, "template.html")
}),
new VueLoaderPlugin()
]
}
Step 4 : 增加npm脚本
"start:vue": "webpack serve --config ./webpack.vue.js"
Step 5: 试一试
npm run start:vue
Vue + Babel Preset
Step 1 : 安装依赖
npm i -D babel-preset-typescript-vue3
# yarn add -D babel-preset-typescript-vue3
Step 2: 写一个webpack.config文件
webpack.vue.withbabel.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {VueLoaderPlugin} = require('vue-loader')
module.exports = {
entry : {
index : './src/main.ts'
},
mode : "development",
module : {
rules : [
{
test : /\.tsx?$/,
loader : "babel-loader",
options : {
presets : [
"@babel/preset-env",
// "babel-preset-typescript-vue3",
"@babel/preset-typescript",
],
plugins : [
"@babel/plugin-vue-jsx"
]
},
exclude : /node_modules/
},
{
test : /\.vue$/,
loader : 'vue-loader'
}
]
},
resolve : {
extensions :['.tsx', '.ts', '.js']
},
output : {
filename : "bundle.[name].js",
path : path.resolve(__dirname, "dist")
},
devServer : {
contentBase : path.resolve(__dirname, "dist"),
port : 3020
},
plugins : [
new HtmlWebpackPlugin({
template : path.resolve(__dirname, "template.html")
}),
new VueLoaderPlugin()
]
}
Step 3 : 配置npm脚本
"start:vue-babel": "webpack serve --config ./webpack.vue.withbabel.js"
Step 4: 执行观察结果
npm run start:vue-babel
2个关键问题:几个问题
1. Babel preset执行顺序有关系吗?
2. preset-react 和preset-vue都在做什么?
但是preset-typescript-vue3只增加了typescript的转化能力。
1