vue组件库npm包安装方式和script引入方式各有啥优缺点
这个问题可以直接问通义千问,答案挺靠谱的。这里总结通义千问的答案:npm 包安装方式更优,结合webpack解决模块依赖、更好的性能优化。
这里举个例子:我们也有实际的项目,如jview的example一样使用resolve.alias引入组件库,这是另一个种形式的npm包方式。它为什么也适用呢?
-
组件库小组内部使用,省去了npm包发布更新和安装更新
-
如果组件库其他组也用,那还是npm包发布更好。
组件库npm包安装的方式更优,但是前端组毅然决定使用script方式,理由是更简单。
笨组件就像AndyView
项目地址:github.com/jovenwang12...
-
src/index.js不导出install方法
- 要保证有window.Vue变量, window.Vue.use才不会报错,install方法会执行,注册组件。
js
// 定义一个 Vue 插件
const install = function (Vue) {
// 遍历组件集合,将每个组件全局注册
components.forEach(component => {
Vue.component(component.name, component)
})
Vue.prototype.$message = Message
// 可能还有其他的全局注册操作,例如指令、过滤器等
}
window.Vue.use({install})
// 导出插件
export default {
version: '1.0.0',
...components
}
- webpack.config.js 导出andyview.js和andyview.css
js
// webpack.config.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
module.exports = {
entry: './src/index.js',
mode: 'production',
output: {
filename: 'andyview.js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'umd',
libraryExport: 'default',
library: 'AndyView',
clean: true
},
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader'
},
{
test: /.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
},
{
test: /.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
// 配置其他loader,如css-loader、file-loader等
]
},
optimization: {
minimizer: [
new CssMinimizerWebpackPlugin()
]
},
plugins: [
new VueLoaderPlugin(),
// 单独提取css文件
new MiniCssExtractPlugin({
filename: 'andyview.css'
})
],
externals: {
vue: 'Vue'
}
}
- examples/main.js, 添加window.Vue变量,andyview.js需要
js
// examples/main.js
import Vue from 'vue'
import App from './App.vue' // 你的示例App组件
// 添加全局变量Vue,给AndyView使用
window.Vue = Vue
new Vue({
render: h => h(App)
}).$mount('#app')
-
examples/index.html引入css, andyview.js引入加上defer
- 因为andyview.js依赖window.Vue,而window.Vue在入口js里,webpack打包后,默认最后加载执行。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<link rel="stylesheet" href="andyview.css">
<script defer src="andyview.js"></script>
</body>
</html>
- examples/webpack.conf.js设置webpack devServer的静态资源目录,也就是上一步骤静态资源的目录
js
// examples/webpack.config.js
devServer: {
port: 8080,
// 静态资源目录
static: {
directory: resolve('../dist')
}
}
- App.vue使用组件,j-button组件会报错,所以额外添加一个button按钮
html
<template>
<div>
<h1>这里是示例</h1>
<j-button type="success" @click="handleClick">andyView按钮</j-button>
<button type="success" @click="handleClick">普通按钮</button>
</div>
</template>
<script>
export default {
methods: {
handleClick () {
this.$message.success('搞错了,再来')
}
}
}
</script>
运行效果如下
- andyview组件库的按钮显示不正确,控制台提示j-button组件是否并没注册?
- 两个按钮点击,弹框都OK
笨组件库的问题
为什么examples运行效果,j-button的提示是否没有注册?按钮点击事件正确?
-
j-button和andyview的button组件,按钮点击事件是andyview的message组件,两者都需要andyview的install方法触发注册(断点测试)
-
webpack构建main.js和App.vue会被打进同一个bundle.js,andyview.js依赖main.js的window.Vue,j-button又依赖andy.js组件注册。所以本质上是andy.js和bundle.js互相依赖。
-
App.vue的渲染,j-button是刚进入页面就要初始化的,这时候andyview.js还没执行;按钮点击this.$message.sucess方法是点击触发的,手速和andy.js的执行未知。
总结笨组件库的问题如下:
-
页面初始化即使用andyview.js的组件,会报错。声明式组件根本无法用。
-
andyview.js没有webpack管理,依赖处理复杂,也无法受益于webpack splitChunks,不利于性能优化。
-
andy.js依赖window.Vue,代码可维护性差。前端进入工程化时代,不轻易暴露全局变量。
-
组件库使用API对用户不友好,很容易掉坑。比如模板html引入andy.js需要加defer, 需要注册window.Vue,不能页面初始化时调用andyview.js的API
总结
Vue组件库的最佳实践:组件库导出install方法,发布npm包;项目使用安装Vue组件库,入口js Vue.use(组件库)
.
详细项目地址:github.com/jovenwang12...
BTW,听说iphone16国行版要集成百度文心一言。我也试用了文心一言技术问题,完全不行。