教你搭建按需加载的Vue组件库(小结)

按需加载的原理

按需加载,本质上是把一个组件库的不同组件 拆分成不同文件 ,按照需要引用对应的文件,而该文件暴露一个 install方法 ,供Vue.use使用。 比如:我只想引用element库里的一个Button组件

import Button from 'element-ui/lib/Button.js'
import Button from 'element-ui/lib/theme-chalk/Button.css'

Vue.use(Button);

上面的写法比较繁琐,而且需要知道每个组件的实际路径,使用起来并不方便,所以我们还需要借助一个转换插件。

先来看看 element 是怎么做的,官方的的「快速手上」:

element使用一个了babel插件,作用就是代码转换:

import { Button } from 'components'

// 转换为

var button = require('components/lib/button')
require('components/lib/button/style.css')

到这我们可以知道,要搭建一个按需加载的组件库。 主要工作 需要两点:

  1. 组件独立打包 ,单个文件对应单个组件
  2. 引入 代码转换 的插件

组件代码的编写规范

我们在项目的跟目录建一个文件夹packages,下面放我们的组件:

packages下每一个文件夹对应一个组件所需要的资源,在index.js定义组件的install方法。而packages/index.js存放了在全量加载时用的install方法

packages/Button/index.js:

import Button from './src/main';

Button.install = function(Vue) {
 Vue.component(Button.name, Button);
};

export default Button;

packages/Button/src/main.vue:

<template>
 <div>
  我是一个Button组件
 </div>
</template>

packages/index.js:

import Button from './Button';
import Loading from './Loading';
import LoadMore from './LoadMore';

const components = [
 Button,
 LoadMore,
 Loading
];

const install = function(Vue) {
 components.forEach(component => {
  Vue.component(component.name, component);
 });
}

if (typeof window !== 'undefined' && window.Vue) {
 install(window.Vue)
}

export default {
 install, // 全量引入
 Button,
 LoadMore,
 Loading
};

webpack配置

组件代码写好了,接下来需要配置一下webpack的打包逻辑。我们复用vue-cli生成的模板,在上面做一些必要更改:

多入口

每个组件独立生成一个对应的js和css,这就需要我们在入口处就把组件的引用定义好:

webpack.prod.conf.js:

const entrys = {
  Button: path.resolve(__dirname, '../packages/Button'),
  index: path.resolve(__dirname, '../packages')
};

const webpackConfig = merge(baseWebpackConfig, {
 entry: entrys,
 // ......
});

上述配置每增加一个组件都需要修改entrys,我们可以优化一下,使其 动态生成

webpack.prod.conf.js:

const entrys = require(./getComponents.js)([组件目录入口]);
const webpackConfig = merge(baseWebpackConfig, {
 entry: entrys,
 ......
});

getComponents.js:

const fs = require('fs');
const path = require('path');

/**
 * 判断刚路径是否含有index.js
 * @param {String} dir
 */
function hasIndexJs(dir) {
  let dirs = [];
  try {
    dirs = fs.readdirSync(dir);
  } catch(e) {
    dirs = null;
  }
  return dirs && dirs.includes('index.js');
}

/**
 * 获取指定入口和入口下包含index.js的文件夹的路径
 * @param {String} entryDir
 */
const getPath = function(entryDir) {
  let dirs = fs.readdirSync(entryDir);

  const result = {
    index: entryDir
  };
  dirs = dirs.filter(dir => {
    return hasIndexJs(path.resolve(entryDir, dir));
  }).forEach(dir => {
    result[dir] = path.resolve(entryDir, dir);
  });
  return result;
}

module.exports = getPath;

修改webpack的输出

默认生成的js文件并不支持ES6引入,在这里我们设置成 umd

output: {
  path: config.build.assetsRoot,
  filename: utils.assetsPath('[name].js'),
  library: 'LoadOnDemand',
  libraryTarget: 'umd'
},

配置 babel-plugin-component -D

上面的组件库打包发布到npm上之后。我们在使用的时候npm install babel-plugin-component -D之后,修改一下.babelrc.js:

"plugins": [
  [
   "component",
   {
    "libraryName": "load-on-demand", // 组件库的名字
    "camel2Dash": false, // 是否把驼峰转换成xx-xx的写法
    "styleLibrary": {
     "base": false, // 是否每个组件都默认引用base.css
     "name": "theme" // css目录的名字
    }
   }
  ]
 ],

这里提一下属性 camel2Dash ,默认是开启的,开启状态下假如你的组件名是vueCompoent,引用的css文件会变成vue-component.css。

结语

上面demo的代码放在了个人github github.com/jmx16449196… 大家如果有更好的实现方法,或者我上面还有什么需要更正的错误,欢迎交流。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解vue项目优化之按需加载组件-使用webpack require.ensure

    使用 vue-cli构建的项目,在 默认情况下 ,执行 npm run build  会将所有的js代码打包为一个整体, 打包位置是 dist/static/js/app.[contenthash].js 类似下面的路由代码 router/index.js  路由相关信息,该路由文件引入了多个 .vue组件 import Hello from '@/components/Hello' import Province from '@/components/Province' import Segm

  • vue路由组件按需加载的几种方法小结

    1. 普通加载 使用vue-cli构建项目后,我们会在Router文件夹下面的index.js里面引入相关的路由组件,如: import Hello from '@/components/Hello' import Boy from '@/components/Boy' import Girl from '@/components/Girl' 这样做的结果就是webpack在npm run build的时候会打包成一个整个的js文件,如果页面一多,会导致这个文件非常大,加载缓慢,为了解决这个问题

  • vue按需加载组件webpack require.ensure的方法

    vue-cli是由vue官方发布的快速构建vue单页面的脚手架. 使用 vue-cli构建的项目,在 默认情况下 ,执行 npm run build 会将所有的js代码打包为一个整体, 打包位置是 dist/static/js/app.[contenthash].js 类似下面的路由代码 router/index.js 路由相关信息,该路由文件引入了多个 .vue组件 import Hello from '@/components/Hello' import Province from '@/c

  • Vue.js中用webpack合并打包多个组件并实现按需加载

    前言 随着移动设备的升级.网络速度的提高,用户对于web应用的要求越来越高,web应用要提供的功能越来越.功能的增加导致的最直观的后果就是资源文件越来越大.为了维护越来越庞大的客户端代码,提出了模块化的概念来组织代码.webpack作为一种模块化打包工具,随着react的流行也越来越流行. 使用 Vue 开发项目时,如果要使用其单文件组件特性,必然要使用 webpack 或者 browserify 进行打包,对于大型应用,为了提升加载速度,可以使用 webpack 的 code split 功能

  • vue实现按需加载组件及异步组件功能

    说实话,我一开始也不知道什么叫按需加载组件,组件还可以按需加载???后来知道了 学不完啊...没关系,看我的 按需加载组件,或者异步组件,主要是应用了component的 is 属性 template中的代码: 这里的每一个按钮,都要显示不同的组件,所以我让他们使用了同一个方法名 <template slot-scope="scope"> <el-button type="text" size="mini" @click=&qu

  • 教你搭建按需加载的Vue组件库(小结)

    按需加载的原理 按需加载,本质上是把一个组件库的不同组件 拆分成不同文件 ,按照需要引用对应的文件,而该文件暴露一个 install方法 ,供Vue.use使用. 比如:我只想引用element库里的一个Button组件 import Button from 'element-ui/lib/Button.js' import Button from 'element-ui/lib/theme-chalk/Button.css' Vue.use(Button); 上面的写法比较繁琐,而且需要知道每

  • 手把手教您实现react异步加载高阶组件

    本篇文章通过分析react-loadable包的源码,手把手教你实现一个react的异步加载高阶组件 1. 首先我们想象中的react异步加载组件应该如何入参以及暴露哪些API? // 组件应用 import * as React from 'react'; import ReactDOM from 'react-dom'; import Loadable from '@component/test/Loadable'; import Loading from '@component/test/

  • vite2.x实现按需加载ant-design-vue@next组件的方法

    1.使用版本 vite:2.0 ant-design-vue: 2.0.0-rc.8 vue:3.0.5 2.安装vite插件 yarn add vite-plugin-style-import -D or npm i vite-plugin-style-import -D 插件仓库地址:github 3.vite.config.js配置 import vue from '@vitejs/plugin-vue' import styleImport from 'vite-plugin-style

  • Extjs4.1.x 框架搭建 采用Application动态按需加载MVC各模块完美实现

    中午的时候发了第一篇 Extjs4.1.x 框架搭建 采用Application动态按需加载MVC各模块 ,发现实现上还是有问题,有很多理解不到位的地方,晚上详细解决下了,终于实现MVC各模块按需加载了,哈皮. 上篇文章中,关于ExtJs这个玩意的评论就跟java和.Net那个好一样,既然上了贼船,就难下了,而且对于企业级的应用我个人觉得Extjs框架还是不错的,尤其是没有UI设计的团队(苦逼的程序员就兼UI吧),起码难得发现一个做的比较好的UI框架(国产的miniUI貌似看的过去,其他的就有点

  • 详解基于angular路由的requireJs按需加载js

    最近终于不忙了!!有时间沉淀一下之前学到的angular东东!! angular路由想必大家已经不陌生了!(陌生的去看我之前那篇手把手教你配置angular路由!) angular路由作为单页面应用,切换页面的时候都是一个页面,所以切换controller和按需加载控件js就成了大问题!!折腾了我半天啊,angular-route内置的办法也没有解决这个问题,最终我是用requireJs解决的这个问题!!上代码! 1.首先引入requireJs,并且在它的下面用闭包写配置 requirejs([

  • react脚手架如何配置less和ant按需加载的方法步骤

    前言 create-react-app是由React官方提供并推荐使用构建新的React单页面应用程序的最佳方式,其构建的项目默认是不支持less的,需要我们手动集成 一.react脚手架搭建 1.先全局安装create-react-app(提前需要安装node) npm install -g create-react-app 2.然后通过create-react-app创建项目my-app create-react-app my-app 3.最后通过cd进入项目文件夹并启动 cd my-app

  • 探索angularjs+requirejs全面实现按需加载的套路

    在进行有一定规模的项目时,通常希望实现以下目标:1.支持复杂的页面逻辑(根据业务规则动态展现内容,例如:权限,数据状态等):2.坚持前后端分离的基本原则(不分离的时候,可以在后端用模版引擎直接生成好页面):3.页面加载时间短(业务逻辑复杂就需要引用第三方的库,但很可能加载的库和用户本次操作没关系):4,还要代码好维护(加入新的逻辑时,影响的文件尽量少). 想同时实现这些目标,就必须有一套按需加载的机制,页面上展现的内容和所有需要依赖的文件,都可以根据业务逻辑需要按需加载.最近都是基于angula

  • 自定义require函数让浏览器按需加载Js文件

    前言 本文介绍的是自定义require函数让浏览器实现按需加载Js文件,那到底要怎么自己写一个按需加载的库呢 为了实现按需加载: //这是我们要实现的功能,require('str.js')时加载str.js文件,并创建一个叫str对象,等加载完毕之后执行str对象的ready方法里的函数. var str = require('str.js'); str.ready(show); //要执行的函数 function show(res){ console.log(res); } //str.js

  • jQuery按需加载轮播图(web前端性能优化)

    引言 关于幻灯轮播图,想必大家都不陌生,尤其是基于 jQuery 的,插件.代码网上一搜一大堆,但是真正符合自己需求的几乎没有,所以我要打造一个符合自身需求,经得起广大网民考验的 jQuery 轮播图! 思路 为什么说网上其他一些轮播图不符合我的要求?我的需求又是什么呢? 现在网上可以找到的多数幻灯轮播图的 jQuery 插件的作法是,先把图片和链接的 HTML 写好,然后控制隐藏和显示来轮流展示当前的幻灯图片.但是对用户而言,我们始终只是看到当前的一张图片,那其他几张隐藏的图片为什么要事先加载

随机推荐