按需加载

在使用 lodash 的时候我们可以使用这样的代码

//一
import {omit} from "lodash";
//二
import l from "lodash";
l.omit();
//三
import omit from "lodash/omit";

以上三种情况都可以使用 lodash,但是区别在于打包之后对框架的引入程度的不同,第一种方法和第二种方法都是将整个库全部都引入,打包之后是 500 多 k 的引入大小,而第三种方法只是将当前函数及其依赖函数给引入,打包文件大小仅有 6k。可以看出按需加载在打包大小和打包速度上有极大的优势。

查看打包大小

使用 webpack 的插件 webpack-bundle-analyzer,可以通过 webpack 设置 node 环境来进行开发和生产环境下的区分

npm install webpack-bundle-analyzer --save-dev

//在webpack.config.js中引入
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; plugins: [
。。。
new BundleAnalyzerPlugin(),
。。。
]

这样在打包 npm start 或者 npm run build 之后就可以进行打包文件大小的查看了



实践

最近将一个之前照着 underscore 实现的一个函数库进行了 es6 改造,但是在使用中发现并没有实现按需加载。于是就开始了一系列的按需加载的实践与改造,最终使用的方法是 babel 插件的方式实现的。

进行单独文件分离

最初的实现是使用umd的方式进行模块化兼容,所有的大类方法比如array全部写到了array文件夹下的index.js里面,现在将单独的方法放到单独的文件里面。



新建babel插件

在node_modules中新建babel-plugin-kiana-demand-loading文件夹,再添加一个index.js文件,写入内容

const babel = require('babel-core');
const types = require('babel-types'); const array_types = ["flatten"]; module.exports = function (babel) {
return {
visitor: {
ImportDeclaration(path, ref = {opts: {}}) {
let node = path.node;
let {specifiers} = node;
if (ref.opts.library === node.source.value
&& !types.isImportDefaultSpecifier(specifiers[0])
&& !types.isImportNamespaceSpecifier(specifiers[0])) {
let newImports = specifiers.map(specifier => {
if (array_types.includes(`${specifier.local.name}`)) {
//node.source.value => kiana-js
//specifier.local.name => flatten
//path => kiana-js/arrays/flatten
return types.importDeclaration([types.importSpecifier(specifier.local, specifier.local)], types.stringLiteral(`${node.source.value}/kiana/arrays/${specifier.local.name}`))
}
return types.importDeclaration([types.importDefaultSpecifier(specifier.local)], types.stringLiteral(`${node.source.value}/kiana/${specifier.local.name}`))
});
path.replaceWithMultiple(newImports)
}
}
}
}
};

然后执行npm run build后可以根据出现的分析发现,仅仅就引入了一个函数的大小

看到分析发现当前引入的内容仅有flatten和该函数所依赖的object方法,剩下的都没有引入。基本成功,剩下的就是继续拆分和优化了。

npm更新版本

函数库做完了,可以下载引入使用,可以直接安装github上的包。这是是发布到npm上进行管理的安装。

npm login

进行npm的登录,没有账号的官网注册。必须登录

npm publish

将当前库文件进行发布,可以创建一个.npmignore将不想发布的文件或文件夹过滤掉

npm version <update_type>

  • 直接使用npm version是查看当前包和当前所有依赖包的版本
  • 查看单独的包用npm view kiana-js versions,这样就是查看当前发布包的版本。
  • 参数<update_type>有三个参数
    • patch补丁,例如version 1.0.0 => version 1.0.1
    • minor修改,例如version 1.0.0 => version 1.1.0
    • major大版本,例如version 1.0.0 => version 2.0.0

流程

npm login => npm publish(如果没发布过) => npm version xxx => npm publish => npm view xxx versions(可以不看)

Docs

babel 修改抽象语法树——入门与实践

写一个 babel 插件实现按需打包的功能

babel-core

babel-types

按需加载实践

babel-plugin-on-demand-loading

如何更新自己写的npm包(模块

记一次按需加载和npm模块发布实践的更多相关文章

  1. Extjs4.1.x使用Application动态按需加载MVC各模块

    我们知道Extjs4之后提出了MVC模块开发,将以前肥厚的js文件拆分成小的js模块[model\view\controller\store\form\data等],通过controller拼接黏合, ...

  2. Webpack按需加载一切皆模块

    前言 在学习 Webpack 之前,我们需要了解一个概念:模块. 何为模块? 如果你曾学过 Java , C# 之类的语言,一定会知道 Java 中的 import 或 C# 中的 using 吧? ...

  3. 按需加载.js .css文件

    首先,理解按需加载当你需要用到某个js里面的函数什么鬼,或者某个css里的样式的时候你才开始加载这个文件. 然后是怎样实现的,简单来说就是在js中动态的createElem<script> ...

  4. Angular (SPA) WebPack模块化打包、按需加载解决方案完整实现

    文艺小说-?2F,言情小说-?3F,武侠小说-?9F long long ago time-1-1:A 使用工具,long long A ago time-1-2:A 使用分类工具,long long ...

  5. angularJS 按需加载

    之前做应用的时候都会在首页就把全站的js预先加载进来... 怎么实现按需加载? 首先在$routeProvider里面加resolve属性,angular-route提供的resolve功能,也就是路 ...

  6. react-router配合webpack实现按需加载

    很久没有写博客了.一直感觉没有什么要写的,但是这个东西确实有必要的.使用react开发,不可能一直打包到一个文件.小项目肯定没有问题,但是变大一旦到几兆,这个问题就很严重.现在又Commonjs,AM ...

  7. requirejs按需加载angularjs文件

    之前分享了一篇用ocLazyLoad实现按需加载angular js文件的博客.本来当时想会使用一种方法就行了.可最近刚好有时间,在网上查找了一下requirejs实现angular js文件按需加载 ...

  8. angularjs ocLazyLoad分步加载js文件,angularjs ocLazyLoad按需加载js

    用angular有一段时间了,平日里只顾着写代码,没有注意到性能优化的问题,而今有时间,于是捋了捋,讲学习过程记录于此: 问题描述:由于采用angular做了网页的单页面应用,需要一次性在主布局中将所 ...

  9. AngularJS中的按需加载ocLazyLoad

    欢迎大家讨论与指导 : ) 初学者,有不足的地方希望各位指出 一.前言 ocLoayLoad是AngularJS的模块按需加载器.一般在小型项目里,首次加载页面就下载好所有的资源没有什么大问题.但是当 ...

随机推荐

  1. struts2 上传与下载

    1.Struts.xml <action name="addfileAction" class="Action.addfileAction"> &l ...

  2. Java基础-工厂设计模式(三锅的肥鸡)

    ---恢复内容开始---   1)还没有工厂时代:假如还没有工业革命,如果一个你要一架飞机,一般的做法是自己去建造一架飞机,然后拿来开 通常的结果就是 有些时候 要么专科螺钉 没打好  要么就是 那个 ...

  3. java基于BasicPlayer调用 播放音乐

    无聊中想想用java调用下听音乐的api.晚上很多文章用的比较老大方法了,都是用原生的代码写,而且不支持mp3格式,BasicPlayer第三方包提供了很好的api调用,简单的3行代码就可以调用mp3 ...

  4. 基于Orangpi Zero和Linux ALSA实现WIFI无线音箱(一)

    作品已经完成,先上源码: https://files.cnblogs.com/files/qzrzq1/WIFISpeaker.zip 全文包含三篇,这是第一篇,作为前言和概述. 第二篇:基于Oran ...

  5. HashMap 实现及原理

    1.为什么用HashMap? HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射HashMap采用了数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和 ...

  6. Exp6 信息搜集与漏洞扫描 20164312 马孝涛

    1.实践内容 (1)各种搜索技巧的应用  (2)DNS IP注册信息的查询  (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测.具体服务的查点(以自己主机为目标)  (4)漏洞扫描:会扫, ...

  7. 运用《深入理解Java虚拟机》书中知识解决实际问题

    前言 以前看别人博客说看完<深入理解Java虚拟机>这本书并没有让自己的编程水平提高多少,不过却大大提高了自己的装逼水平.其实,我倒不这么认为,至少在我看完一遍这本书后,有一种醍醐灌顶的感 ...

  8. Asp.Net Core中HttpClient的使用方式

    在.Net Core应用开发中,调用第三方接口也是常有的事情,HttpClient使用人数.使用频率算是最高的一种了,在.Net Core中,HttpClient的使用方式随着版本的升级也发生了一些变 ...

  9. Redis的正确使用姿势

    前言 说到分布式缓存,可能大多数人脑海浮现的就是redis了,为什么redis能够在竞争激烈的缓存大战中脱颖而出呢?原因无非有一下几点:性能好,丰富的特性跟数据结构,api操作简单.但是用的人多了,就 ...

  10. 贾天昊 - Nick