记一次按需加载和npm模块发布实践
按需加载
在使用 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模块发布实践的更多相关文章
- Extjs4.1.x使用Application动态按需加载MVC各模块
我们知道Extjs4之后提出了MVC模块开发,将以前肥厚的js文件拆分成小的js模块[model\view\controller\store\form\data等],通过controller拼接黏合, ...
- Webpack按需加载一切皆模块
前言 在学习 Webpack 之前,我们需要了解一个概念:模块. 何为模块? 如果你曾学过 Java , C# 之类的语言,一定会知道 Java 中的 import 或 C# 中的 using 吧? ...
- 按需加载.js .css文件
首先,理解按需加载当你需要用到某个js里面的函数什么鬼,或者某个css里的样式的时候你才开始加载这个文件. 然后是怎样实现的,简单来说就是在js中动态的createElem<script> ...
- Angular (SPA) WebPack模块化打包、按需加载解决方案完整实现
文艺小说-?2F,言情小说-?3F,武侠小说-?9F long long ago time-1-1:A 使用工具,long long A ago time-1-2:A 使用分类工具,long long ...
- angularJS 按需加载
之前做应用的时候都会在首页就把全站的js预先加载进来... 怎么实现按需加载? 首先在$routeProvider里面加resolve属性,angular-route提供的resolve功能,也就是路 ...
- react-router配合webpack实现按需加载
很久没有写博客了.一直感觉没有什么要写的,但是这个东西确实有必要的.使用react开发,不可能一直打包到一个文件.小项目肯定没有问题,但是变大一旦到几兆,这个问题就很严重.现在又Commonjs,AM ...
- requirejs按需加载angularjs文件
之前分享了一篇用ocLazyLoad实现按需加载angular js文件的博客.本来当时想会使用一种方法就行了.可最近刚好有时间,在网上查找了一下requirejs实现angular js文件按需加载 ...
- angularjs ocLazyLoad分步加载js文件,angularjs ocLazyLoad按需加载js
用angular有一段时间了,平日里只顾着写代码,没有注意到性能优化的问题,而今有时间,于是捋了捋,讲学习过程记录于此: 问题描述:由于采用angular做了网页的单页面应用,需要一次性在主布局中将所 ...
- AngularJS中的按需加载ocLazyLoad
欢迎大家讨论与指导 : ) 初学者,有不足的地方希望各位指出 一.前言 ocLoayLoad是AngularJS的模块按需加载器.一般在小型项目里,首次加载页面就下载好所有的资源没有什么大问题.但是当 ...
随机推荐
- 集成支付宝SDK流程
5.2 SDK集成流程 5.2.1 iOS 解压接口压缩文件(文件名是 WS_MOBILE_PAY_SDK_BASE.zip),找到iOS的压缩文件(文件名是支付宝移动支付SDK 标准版(iOS).z ...
- Windows上安装配置SSH教程(2)——在Windows XP和Windows 10上安装并配置OpenSSH for Windows
知识点汇总:http://www.cnblogs.com/feipeng8848/p/8559803.html ------------------------ 安装方式有3种: (1)Windows ...
- Java开源生鲜电商平台-优惠券设计与架构(源码可下载)
Java开源生鲜电商平台-优惠券设计与架构(源码可下载) 说明:现在电商白热化的程度,无论是生鲜电商还是其他的电商等等,都会有促销的这个体系,目的就是增加订单量与知名度等等 那么对于Java开源生鲜电 ...
- 自学Python,新手上路,好资源免费分享
Python 可以用来做什么? 在我看来,基本上可以不负责任地认为,Python 可以做任何事情.无论是从入门级选手到专业级选手都在做的爬虫,还是Web 程序开发.桌面程序开发还是科学计算.图像处理, ...
- quillJS 富文本编辑器源码分析系列1
quillJS 富文本编辑器目前是一款很火富文本编辑器,使用广泛,github 上面的 star 有 22,492,虽然说不以 star 论英雄,不过这可以说明它还是比较受欢迎的: 它的特点是:轻量, ...
- :Android网络编程--XML之解析方式:SAX
任何放置在资源(res)目录下的内容可以通过应用程序的R类访问,这是被Android编译过的,而任何放置在资产(assets)目录下的内容会保持它的原始文件格式,为了读取它们,必须使用AssetMan ...
- Haskell学习-monad
原文地址:Haskell学习-monad 什么是Monad Haskell是一门纯函数式的语言,纯函数的优点是安全可靠.函数输出完全取决于输入,不存在任何隐式依赖,它的存在如同数学公式般完美无缺.可是 ...
- Python爬虫入门教程 55-100 python爬虫高级技术之验证码篇
验证码探究 如果你是一个数据挖掘爱好者,那么验证码是你避免不过去的一个天坑,和各种验证码斗争,必然是你成长的一条道路,接下来的几篇文章,我会尽量的找到各种验证码,并且去尝试解决掉它,中间有些技术甚至我 ...
- 开箱即用Bumblebee独立部署搭建webapi网关详解
在之前的章节里都是讲述如何在程序中使用Bumblebee来构建一个Webapi网关:但这样显然有些麻烦,毕竟很多时候可能只需要一个简单负载处理,还需要写个程序针对服务进行编写代码或配置的确是比较麻烦的 ...
- 如何通过get,set方法访问到父类的私有属性
刚学习继承的时候,总是会有这样的疑问. 子类继承父类时,会继承所有的非私有的属性和方法.那么在用set方法修改父类的私有属性时,怎么没有报空指针异常呢? 后来仔细想过这个问题,既然没有报空指针,那么在 ...