1. 程式人生 > >記一次按需加載和npm模塊發布實踐

記一次按需加載和npm模塊發布實踐

doc 都沒有 bject 寫入 中新 pre default login web

按需加載

在使用 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

  • 直接使用npm version是查看當前包和當前所有依賴包的版本
  • 查看單獨的包用npm view kiana-js versions,這樣就是查看當前發布包的版本。
  • 參數有三個參數
    • 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模塊發布實踐