Vue使用Rollup編寫tsx組件庫
注意
這套配置方案遇到個問題:在我的家庭版 win10 系統(tǒng)中,rollup build 打包會報錯 can not resolve xxx筐付, 即無法解析 import 路徑的問題,但是我嘗試過沮尿,在我的專業(yè)版win10系統(tǒng)中沒有問題,還有在 Ubuntu 系統(tǒng)中也沒有問題赴邻;
這個問題很奇怪啡捶,似乎 rollup 對家庭版 win10 并不兼容,所以建議各位系統(tǒng)盡量使用專業(yè)版的windows系統(tǒng)
感謝以下資料
- 如使用Typescript擼Vue(Vue2 + TS +TSX+CSS module)
https://zhuanlan.zhihu.com/p/58351868
步驟
- 安裝環(huán)境
安裝以下3個輔助庫彤敛,這便是關鍵墨榄,缺一不可勿她,否則無法實現(xiàn)用 class 編寫 tsx 的 vue 組件
yarn add vue-class-component -D
yarn add vue-property-decorator -D
yarn add vue-tsx-support -D
安裝 sass 庫(樣式庫看個人喜好,選擇 less 還是 sass 無所謂)
yarn add node-sass -D
yarn add sass-loader -D
安裝其他輔助庫(主要參考下面給出的 package.json 腳本中的依賴即可之剧,缺什么加什么)
yarn add -D rollup-plugin-typescript2
yarn add -D rollup-plugin-peer-deps-external
yarn add -D rollup-plugin-scss
...
創(chuàng)建 rollup 倉庫
臨時使用 rollup 針對 vue 的腳手架猪狈,快速創(chuàng)建 vue 的 rollup 組件庫工程
在 vue-sfc-rollup 的步驟提示中辩恼,一定記得選擇 typescript
npx vue-sfc-rollup在 entry.ts 中 import ts檢查腳本
import "vue-tsx-support/enable-check";
- 我的 package.json 中的所有依賴,請按照我的配置疆前,有些依賴一定要放到 peerDependencies 讓 rollup 作為外部依賴進行打包處理
{
"name": "mq-components",
"version": "1.0.0",
"description": "",
"main": "dist/mq-components.ssr.js",
"browser": "dist/mq-components.esm.js",
"module": "dist/mq-components.esm.js",
"unpkg": "dist/mq-components.min.js",
"types": "mq-components.d.ts",
"files": [
"dist/*",
"mq-components.d.ts",
"src/**/*.tsx"
],
"scripts": {
"serve": "vue-cli-service serve dev/serve.ts",
"build": "cross-env NODE_ENV=production TARGET=web-standalone-dev rollup --config build/rollup.config.js",
"build:ssr": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format cjs",
"build:es": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format es",
"build:unpkg": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format iife"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@babel/preset-typescript": "^7.9.0",
"@rollup/plugin-alias": "^2.2.0",
"@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-replace": "^2.3.2",
"@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
"@vue/babel-preset-jsx": "^1.2.2",
"@vue/cli-plugin-babel": "^4.3.1",
"@vue/cli-plugin-typescript": "^4.3.1",
"@vue/cli-service": "^4.3.1",
"cross-env": "^7.0.2",
"minimist": "^1.2.5",
"node-sass": "^4.14.1",
"rollup": "^2.7.3",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-peer-deps-external": "^2.2.3",
"rollup-plugin-scss": "^2.6.1",
"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-typescript2": "^0.28.0",
"rollup-plugin-vue": "^5.1.6",
"sass-loader": "^10.0.3",
"typescript": "^3.8.3",
"vue": "^2.6.11",
"vue-class-component": "^7.2.6",
"vue-property-decorator": "^9.0.2",
"vue-template-compiler": "^2.6.11",
"vue-tsx-support": "^2.3.3"
},
"peerDependencies": {
"element-ui": "^2.13.2",
"vue": "^2.6.11",
"vue-tsx-support": "^3.0.2"
},
"engines": {
"node": ">=10"
}
}
刪除根目錄下的 shims-tsx.d.ts ,否則會報重復定義的錯誤
vue-src-rollup 自動生成的 rollup.config.js 腳本中的代碼都刪除米辐,然后寫入我下面的配置腳本
// rollup.config.js
// 下面 import 的一些庫,這里沒用到赊窥,是原來 vue-sfc-rollup 自動生成的狸页,
// 我沒刪除,是因為后續(xù)優(yōu)化可能會用到址遇,作為提醒自己,以免忘記
import fs from 'fs'
import path from 'path'
import vue from 'rollup-plugin-vue'
import external from 'rollup-plugin-peer-deps-external'
import typescript from 'rollup-plugin-typescript2'
import scss from 'rollup-plugin-scss'
import alias from '@rollup/plugin-alias'
import commonjs from '@rollup/plugin-commonjs'
import replace from '@rollup/plugin-replace'
import resolve from '@rollup/plugin-node-resolve'
import babel from 'rollup-plugin-babel'
import { terser } from 'rollup-plugin-terser'
import minimist from 'minimist'
const projectRoot = path.resolve(__dirname, '..')
const argv = minimist(process.argv.slice(2))
const globals = {
vue: "Vue" // 告訴rollup全局變量Vue即是vue
}
const ourPutDir = 'lib'
// default
let output = {
dir: ourPutDir,
format: 'es',
globals
}
// console.log(" argv.format = ",argv.format)
if (argv.format && argv.format === 'es') {
console.log(" es argv.format = ", argv.format);
output = {
dir: ourPutDir,
format: 'esm',
exports: 'named',
}
} else if (argv.format && argv.format === 'cjs') {
console.log(" cjs argv.format = ", argv.format);
output = {
compact: true,
dir: ourPutDir,
format: 'cjs',
name: 'MqComponents',
exports: 'named',
globals,
}
} else if (argv.format && argv.format === 'iife') {
console.log(" iife argv.format = ", argv.format)
output = {
compact: true,
dir: ourPutDir,
format: 'iife',
name: 'MqComponents',
exports: 'named',
globals,
}
}
export default {
input: 'src/index.ts',
output,
plugins: [
external(),
alias({
resolve: ['.js', '.jsx', '.ts', '.tsx'],
entries: {
'@': path.resolve(projectRoot, 'src'),
},
}),
scss({
output: path.resolve(projectRoot, ourPutDir + '/main.css'),
}),
typescript(),
resolve({
extensions: ['.ts', '.tsx', '.js', '.jsx']
}),
commonjs(),
babel({
exclude: 'node_modules/**',
extensions: ['.js', '.jsx', '.ts', '.tsx'],
presets: ["@vue/babel-preset-jsx"]
}),
]
}
- 最后可以在 src 下面編寫自己的 tsx 腳本了,下面給出一份案例
【src/lib-components/template-sample/style.scss】
.container {
background-color: red;
}
【src/lib-components/template-sample/index.tsx】
import { Component } from 'vue-property-decorator';
import {
Component as TsComponent
} from "vue-tsx-support";
import './style.scss';
export interface ITemplateSampleProps{
}
@Component
export default class TemplateSample extends TsComponent<ITemplateSampleProps>{
protected render(){
return (<div class="container">hello every one</div>)
}
}