likes
comments
collection
share

我是如何用GPT优化vue组件库的(下)

作者站长头像
站长
· 阅读数 2

vue组件库npm包安装方式和script引入方式各有啥优缺点

这个问题可以直接问通义千问,答案挺靠谱的。这里总结通义千问的答案:npm 包安装方式更优,结合webpack解决模块依赖、更好的性能优化。

这里举个例子:我们也有实际的项目,如jview的example一样使用resolve.alias引入组件库,这是另一个种形式的npm包方式。它为什么也适用呢?

  1. 组件库小组内部使用,省去了npm包发布更新和安装更新

  2. 如果组件库其他组也用,那还是npm包发布更好。

组件库npm包安装的方式更优,但是前端组毅然决定使用script方式,理由是更简单。

笨组件就像AndyView

项目地址:github.com/jovenwang12…

  1. src/index.js不导出install方法

    1. 要保证有window.Vue变量, window.Vue.use才不会报错,install方法会执行,注册组件。
// 定义一个 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
}
  1. webpack.config.js 导出andyview.js和andyview.css
// 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'
  }
}
  1. examples/main.js, 添加window.Vue变量,andyview.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')
  1. examples/index.html引入css, andyview.js引入加上defer

    1. 因为andyview.js依赖window.Vue,而window.Vue在入口js里,webpack打包后,默认最后加载执行。
<!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>
  1. examples/webpack.conf.js设置webpack devServer的静态资源目录,也就是上一步骤静态资源的目录
// examples/webpack.config.js
  devServer: {
    port: 8080,
    // 静态资源目录
    static: {
      directory: resolve('../dist')
    }
  }
  1. App.vue使用组件,j-button组件会报错,所以额外添加一个button按钮
<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>

运行效果如下

  1. andyview组件库的按钮显示不正确,控制台提示j-button组件是否并没注册?
  2. 两个按钮点击,弹框都OK

我是如何用GPT优化vue组件库的(下)

笨组件库的问题

为什么examples运行效果,j-button的提示是否没有注册?按钮点击事件正确?

  1. j-button和andyview的button组件,按钮点击事件是andyview的message组件,两者都需要andyview的install方法触发注册(断点测试)

  2. webpack构建main.js和App.vue会被打进同一个bundle.js,andyview.js依赖main.js的window.Vue,j-button又依赖andy.js组件注册。所以本质上是andy.js和bundle.js互相依赖。

  3. App.vue的渲染,j-button是刚进入页面就要初始化的,这时候andyview.js还没执行;按钮点击this.$message.sucess方法是点击触发的,手速和andy.js的执行未知。

总结笨组件库的问题如下:

  1. 页面初始化即使用andyview.js的组件,会报错。声明式组件根本无法用。

  2. andyview.js没有webpack管理,依赖处理复杂,也无法受益于webpack splitChunks,不利于性能优化。

  3. andy.js依赖window.Vue,代码可维护性差。前端进入工程化时代,不轻易暴露全局变量。

  4. 组件库使用API对用户不友好,很容易掉坑。比如模板html引入andy.js需要加defer, 需要注册window.Vue,不能页面初始化时调用andyview.js的API

总结

Vue组件库的最佳实践:组件库导出install方法,发布npm包;项目使用安装Vue组件库,入口js Vue.use(组件库).

详细项目地址:github.com/jovenwang12…

BTW,听说iphone16国行版要集成百度文心一言。我也试用了文心一言技术问题,完全不行。