阅读 175

组件库建设--基本框架(从0到1)

开发环境

pc环境:windows webpack:5.3.9 webpack-cli:4.9.1 webpack-dev-server: 4.3.1 【全局安装webpack,webpack-cli,webpack-dev-server】

目录结构

  • components ui组件

  • docs 文档库

引入方式

全局引入 通过vue.use引入

创建组件

  • 在src/components目录下新建A目录,在A目录里面新建A.vue

  • 创建index.js,将A.vue导出

注意:name要与组件名称一致,比如A.vue,name也应该是A

import A from './A.vue' export default A 复制代码

全局引入

  • 在src目录下,新建index.js,通过install方法进行注册

import A from './components/A' const components = {     A, } const install = (Vue) => {     Object.keys(components).map((key) => {         const component = components[key]         Vue.component(component.name, component)     }) } // auto install if (typeof window !== 'undefined' && window.Vue) {     install(window.Vue); } const HBirthDay = {     install } export default HBirthDay //module.exports.default = module.exports = HBirthDay 复制代码

打包

这里的打包,我们参考element-ui,通过打包成一个js文件,我们在其他项目里面通过vue.use引入

  • webpack.common.js

/**  * 公共配置  */ const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const { VueLoaderPlugin } = require('vue-loader') const webpack = require('webpack') const MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = { output: { path: path.join(__dirname, 'node_modules/hbirthday'),  // 打包生成文件地址 filename: 'HBirthDay.min.js', // 指定输出文件的名称 libraryTarget: 'umd', library: 'HBirthDay', umdNamedDefine: true }, module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: ['@babel/plugin-transform-runtime'] } }, exclude: /node_modules/ // 不编译node_modules下的文件 }, { // *.vue test: /\.vue$/, loader: 'vue-loader' }, { // 图片 test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use: {                     loader: 'url-loader', options: { limit: 10 * 1024 // 10kb } }             },             // {             //     test: /\.css$/i,             //     use: [MiniCssExtractPlugin.loader,"css-loader"],             // },             {                 test: /\.css$/i,                  use: [                      {                          loader: MiniCssExtractPlugin.loader,                          options: {                              esModule: false,                              publicPath: "../",                          }                      },                      "css-loader",                      {                          loader: 'postcss-loader',                          options: {                              postcssOptions: {                                  plugins: [                                      [                                          'postcss-preset-env',                                      ],                                  ],                              },                          },                      }                  ]             }, ]     }, // 解析路径 resolve: { // 设置src别名         alias: {             'vue': 'vue/dist/vue.esm.js', '@': path.resolve(__dirname, 'src'), }, //后缀名 可以根据需要自由增减         extensions: ['.js', '.vue'] },     plugins: [     new VueLoaderPlugin(),     new MiniCssExtractPlugin({         // 类似于 webpackOptions.output 中的选项         // 所有选项都是可选的         filename: 'assets/css/[name].css',         chunkFilename: 'assets/css/[id].css',     }), new HtmlWebpackPlugin({ filename: 'index.html', // 生成的文件夹名 template: 'public/index.html', // 模板html favicon: 'public/favicon.ico', // 图标 }),         new webpack.optimize.ModuleConcatenationPlugin() ] } 复制代码

  • webpack.dev.js

const webpack = require('webpack') const path = require('path') const { merge } = require('webpack-merge') const common = require('./webpack.common') module.exports = merge(common, {     mode: 'development',     entry: './src/main.js', // 定义入口文件 devServer: { contentBase: path.join(__dirname, 'dist'), // 告诉服务器内容的来源。仅在需要提供静态文件时才进行配置 compress: true,  // 开启压缩 port: 8081,  // 端口 hotOnly: true,  // 热模块替换,保存页面状态 hot: true,   // 自动刷新         open: false,         historyApiFallback: { index: '/index.html' //与output的publicPath有关(HTMLplugin生成的html默认为index.html) }, }, devtool: 'source-map', plugins: [ new webpack.HotModuleReplacementPlugin(), // 配合 devServer:hot 使用,自动刷新页面 ] }) 复制代码

  • webpack.prod.js

const { merge } = require('webpack-merge') const common = require('./webpack.common') const { CleanWebpackPlugin } = require('clean-webpack-plugin') const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); module.exports = merge(common, {     mode: 'production',     entry: './src/index.js', // 定义入口文件     externals: { vue: { root: 'Vue', commonjs: 'vue', commonjs2: 'vue', amd: 'vue' } }, plugins: [         new CleanWebpackPlugin(),         new CssMinimizerPlugin(), ] }) 复制代码

  • package.json

{   "name": "hbirthday",   "version": "1.0.0",   "description": "生日",   "main": "dist/HBirthDay.min.js",   "scripts": {     "dev": "webpack serve --config webpack.dev.js",     "build": "webpack --config webpack.prod.js"   },   "keywords": [],   "author": "hhh",   "license": "ISC",   "devDependencies": {     "@babel/core": "^7.14.3",     "@babel/plugin-transform-runtime": "^7.14.3",     "@babel/preset-env": "^7.14.4",     "@vue/cli-plugin-babel": "^4.5.14",     "babel-loader": "^8.2.2",     "clean-webpack-plugin": "^4.0.0-alpha.0",     "css-loader": "^5.2.6",     "file-loader": "^6.2.0",     "html-webpack-plugin": "^5.3.1",     "less": "^4.1.1",     "less-loader": "^9.1.0",     "style-loader": "^2.0.0",     "url-loader": "^4.1.1",     "vue-loader": "^15.9.7",     "vue-style-loader": "^4.1.3",     "vue-template-compiler": "^2.6.14",     "webpack": "^5.38.1",     "webpack-cli": "^4.7.2",     "webpack-dev-server": "^3.11.2",     "webpack-merge": "^5.8.0"   },   "dependencies": {     "babel-plugin-components": "^1.0.4",     "chalk": "^4.1.1",     "compression-webpack-plugin": "^9.0.0",     "css-minimizer-webpack-plugin": "^3.1.1",     "fa": "^1.0.1",     "hbirthday": "^1.0.0",     "mini-css-extract-plugin": "^2.4.3",     "path": "^0.12.7",     "postcss-loader": "^6.2.0",     "postcss-preset-env": "^6.7.0",     "vue": "^2.6.14",     "vue-router": "^3.5.1",     "vuex": "^3.6.2"   } } 复制代码

全局打包命令

npm run build 复制代码

在这里插入图片描述

使用方式

在这里插入图片描述

npm发布

  • 任务

  1. 完成组件库打包,可通过全局引入组件

  2. 发布到npm公共库,可通过npm方式引入

  • 操作步骤

  • 在package.json main配置里面写入"dist/HBirthDay.min.js",也就是你刚才打包好的js文件,只一步必须,否则无法引入

在这里插入图片描述

  • npm config set registry registry.npmjs.org/

  • npm login

  • npm publish

426错误解决 :blog.csdn.net/weixin_4169…

注意:邮箱必须经过校验,否则会显示登录错误

package.json里面的name在发布时,必须全部小写,不能有大写字母,另外在每次发布需要更改json里面的version,必须与上一次version不一样

在这里插入图片描述

  • 检验是否发布成功

在这里插入图片描述

npm发布成功使用方法

在这里插入图片描述 在这里插入图片描述

局部引入

  • 新建webpack.lib.js文件

const fs = require('fs'); const path = require('path'); const { merge } = require('webpack-merge') const common = require('./webpack.common') const { CleanWebpackPlugin } = require('clean-webpack-plugin') const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); const MiniCssExtractPlugin = require('mini-css-extract-plugin') const join = path.join; const resolve = (dir) => path.join(__dirname, dir); /**  * @desc 大写转横杠  * @param {*} str  */ function upperCasetoLine(str) {   let temp = str.replace(/[A-Z]/g, function (match) {     return "-" + match.toLowerCase();   });   if (temp.slice(0, 1) === '-') {     temp = temp.slice(1);   }   return temp; } /** * @desc 获取组件入口 * @param {String} path */ function getComponentEntries(path) {     let files = fs.readdirSync(resolve(path));     const componentEntries = files.reduce((fileObj, item) => {       //  文件路径       const itemPath = join(path, item);       //  在文件夹中       const isDir = fs.statSync(itemPath).isDirectory();       const [name, suffix] = item.split('.');            //  文件中的入口文件       if (isDir) {         fileObj[upperCasetoLine(item)] = resolve(join(itemPath, 'index.js'))       }       //  文件夹外的入口文件       else if (suffix === "js") {         fileObj[name] = resolve(`${itemPath}`);       }       return fileObj     }, {});          return componentEntries; } module.exports = merge(common, {     mode: 'production',     entry: getComponentEntries('src/components'),     //  输出配置     output: {       //  文件名称       filename: '[name]/index.js',   path:path.resolve(__dirname,'node_modules/hbirthday/lib'),   umdNamedDefine: true,       //  构建依赖类型       libraryTarget: 'umd',       //  库中被导出的项       libraryExport: 'default',       //  引用时的依赖名       library: 'HBirthDay',     },     externals: { vue: { root: 'Vue', commonjs: 'vue', commonjs2: 'vue', amd: 'vue' } }, plugins: [         new CleanWebpackPlugin(), new MiniCssExtractPlugin({ // 类似于 webpackOptions.output 中的选项 // 所有选项都是可选的 filename: '[name]/style.css', chunkFilename: '[id]/[id].css', }),         new CssMinimizerPlugin(),         // new MiniCssExtractPlugin() ] }) 复制代码

这个文件的作用是加载每个组件文件夹里面的index.js,把它们放置在lib文件夹下

  • 组件库里面index.js

import component1 from './src/component1.vue' component1.install = function (Vue) {   console.info('component1----install----')   Vue.component(component1.name, component1) } export default component1 复制代码

这里导出install方法,到时我们就可以通过use方法引入,当然还有第二种方式,代码如下:

import A from './A.vue' export default A 复制代码

通过这种方式,只能通过Vue.component(componentName, component)方式引入

  • package.json增加局部打包命令

"build:lib": "webpack --config webpack.lib.js" 复制代码

  • 结果

在这里插入图片描述 在这里插入图片描述

我们将所有组件都打包在lib目录下,每一个组件目录下都有一个index.js

  • 接下来我们就可以在main.js单独引入这里的文件

在这里插入图片描述

注意这里用了use的方法,是因为我们在组件index.js导出时使用了组件.install方法

在这里插入图片描述

  • 接下来我们转变一下引入方式,改为如下方式

import {component1} from 'hbirthday' // import '组件对应的css文件' Vue.use(componnent1) 复制代码

  • 在package.json里面增加babel配置,安装babel-plugin-component插件

"babel": {    "plugins": [      [        "component",        {          "libraryName": "hbirthday"        }      ]    ]  } 复制代码

  • 结果

在这里插入图片描述


作者:hhh11237
链接:https://juejin.cn/post/7031101581604945933

文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐