最近学习vue的使用,自己不大喜欢用脚手架搭建项目,又热衷于TypeScript 和 React 刚好 又想体验一下webpack4就自己整了这么一个混合型的简单模板.分离css,压缩,dev map 定位==
后续准备加入 服务器渲染 nuxt ui框架 == 有啥建议啥的欢迎一起探讨。
没有写过文章 语文也不及格 排版什么的还请各位大佬见谅勿喷
Git地址:传送门
先讲讲Webpack4的一些配置
跟以前有些不一样
- 提取公共的js模块不用需要使用 内置的 CommonsChunkPlugin 插件 而是多了一个基础配置项 optimizatio
- 启用UglifyJsPlugin压缩只需要配置mode 不在需要引入 UglifyJsPlugin 插件
- webpack4编译使用 awesome-typescript-loader 编译 ts 热更新的时候会报错,改成 ts-loader
optimization 配置如下
// webpack 4删除了CommonsChunkPlugin,以支持两个新选项(optimization.splitChunks和optimization.runtimeChunk)
// https://gist.github.com/sokra/1522d586b8e5c0f5072d7565c2bee693
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all"
}
}
}
},
mode 配置如下
// 打包模式 development。启用NamedModulesPlugin。 production。启用UglifyJsPlugin,ModuleConcatenationPlugin和NoEmitOnErrorsPlugin。
mode: evn.Generative ? 'production' : 'development',
加载配置
vue common 加入到wepback中
resolve: {
extensions: [".ts", ".tsx", ".js", '.vue', ".json"],
// https://github.com/vuejs-templates/webpack/issues/215
alias: {
'vue$': 'vue/dist/vue.common.js',
}
},
ts,tsx,vue的加载配置
{
// vue 配置文档 https://vue-loader.vuejs.org/zh-cn/configurations/pre-processors.html
test: /\.vue$/, loader: 'vue-loader',
include: srcPath,
options: {
loaders: {
ts: 'ts-loader', //编译 vue script 中的 ts
tsx: 'babel-loader!ts-loader',//编译 vue script 中的 tsx
css: styleCss.extract({ //提取css
use: cssOptions.use,
fallback: 'vue-style-loader'
})
}
}
},
//ts 直接编译
{ test: /\.ts$/, include: srcPath, loader: 'ts-loader' },
// vue jsx https://github.com/vuejs/babel-plugin-transform-vue-jsx
// 编译顺序 tsx>es6>babel,vue-jsx>js
{ test: /\.tsx$/, include: srcPath, loader: 'babel-loader!ts-loader' },
tsx 的处理配置
tsconfig.json 文件配置
- jsx 配置成 preserve 这样 ts编译保留jsx语法交给babel 处理
"jsx": "preserve",
- babel 需要下载 transform-vue-jsx 插件 以及依赖插件 我是在 package.json 中配置的插件 看这里
"babel": {
"presets": [
"env"
],
"plugins": [
"transform-vue-jsx"
]
},
- 加入 tsx 加载器 编译顺序 tsx>es6>babel,vue-jsx>js
{ test: /\.tsx$/, include: srcPath, loader: 'babel-loader!ts-loader' },
组件类型 完整代码可以 获取源码查看 传送门
class 模板文件类型 components>class>test1.ts
import Vue from 'vue'
import Component from 'vue-class-component'
import template from './template.html'
// @Component 修饰符注明了此类为一个 Vue 组件
@Component({
// 所有的组件选项都可以放在这里
template
})
export default class extends Vue {
// 初始数据可以直接声明为实例的属性
message = '获取数据!'
list: { id: number, name: string, age: number }[] = [];
loading = false;
// 组件方法也可以直接声明为实例的方法
onClick() {
...
}
}
tsx 类型 components>jsx>test.tsx
import Vue from 'vue'
import Component from 'vue-class-component'
import "./style.css"
// @Component 修饰符注明了此类为一个 Vue 组件
@Component({})
export default class extends Vue {
message = "JSX 组件";
conut = 0;
click(e) {
this.conut++;
console.log(e);
}
sync(prop, value) {
this[prop] = value
}
list: { id: number, name: string, age: number }[] = [];
loading = false;
// 组件方法也可以直接声明为实例的方法
getList() {
this.loading = true;
setTimeout(() => {
const list = [{
id: Math.floor(Math.random() * 10000),
name: "Name" + Math.floor(Math.random() * 100),
age: Math.floor(Math.random() * 100),
}, {
id: Math.floor(Math.random() * 10000),
name: "Name" + Math.floor(Math.random() * 100),
age: Math.floor(Math.random() * 100),
}, {
id: Math.floor(Math.random() * 10000),
name: "Name" + Math.floor(Math.random() * 100),
age: Math.floor(Math.random() * 100),
},];
this.list = [...this.list, ...list];
this.loading = false;
}, 1500);
}
render(h) {
return (
<div class="aaaaaaa">
<p>{this.message}</p>
<input type="text" value={this.conut} on-input={(e) => this.sync('conut', e.target.value)} />
<button onClick={this.click}>Add {this.conut}</button>
<span>{this.message}</span> world!
<div>
<table style="border: 1px solid red;width: 300px">
<tr style="border: 1px solid red">
<td>id</td>
<td>name</td>
<td>age</td>
</tr>
{/* 数据 */}
{this.list.map(t => <tr >
<td style="border: 1px solid red">{t.id}</td>
<td style="border: 1px solid red">{t.name}</td>
<td style="border: 1px solid red">{t.age}</td>
</tr>)}
{/* loading */}
{this.loading ? <tr >
<td colspan="3" style="text-align: center;color: red">Loading...</td>
</tr> : null}
</table>
<button on-click={this.getList}>获取数据</button>
</div>
</div>
)
}
}