教你发布一个按需加载的JS工具包

创建项目

新建文件夹airspeed

执行 npm init

会生成一个简单的json文件:

{
  "name": "airspeed",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

新建src文件夹,再健src/index.js文件。

新建两个object的工具函数:

isEmptyObject.js

/**
 * 
 * @desc   判断`obj`是否为空
 * @param  {Object} obj
 * @return {Boolean}
 */
function isEmptyObject(obj) {
    if (!obj || typeof obj !== 'object' || Array.isArray(obj))
        return false
    return !Object.keys(obj).length
}

module.exports = isEmptyObject

isPlainObject.js


/**
 * @desc 判断obj是否为纯粹的对象{}
 * @param {Object} obj
 * @returns {Boolean}
 */
function isPlainObject(obj) {
  if(typeof obj !== 'object' || !obj) return false;

  var proto = obj;
  while(Object.getPrototypeOf(proto) !== null) {
    proto = Object.getPrototypeOf(proto);
  }
  return Object.getPrototypeOf(obj) === proto;
}
module.exports = isPlainObject;

完成src/index.js文件

这个文件负责把所有的工具函数暴露出去。

const isEmptyObject = require('./object/isEmptyObject.js');
const isPlainObject = require('./object/isPlainObject');


let moduleExports = {
  isEmptyObject,
  isPlainObject
};


module.exports = moduleExports;

上面的这种写法可以简单易懂,但是如果src下面的工具函数越来越多,在index.js文件中的引入将会很长,难以维护,可以使用下面这种方式处理,不需要每次新建一个工具函数就手动引入。

/**
 * @desc webpack打包入口文件  
 * @example 自动引入子目录下所有js文件
 */
 let moduleExports = {};

 const r = require.context('./', true, /^\.\/.+\/.+\.js$/);
 r.keys().forEach(key => {
     let attr = key.substring(key.lastIndexOf('/') + 1, key.lastIndexOf('.'));
     moduleExports[attr] = r(key);
 });
 
 module.exports = moduleExports;

注意:文件名跟方法名同名

配置webpack

这里使用webpack进行打包。

新建scripts文件夹,创建webpack.config.js文件。

zhi cconst path = require('path');

const pkg = require('../package.json');

const rootPath = path.resolve(__dirname, '../');

const config = {
  mode: 'production',
  entry: path.resolve(rootPath,'src', 'index.js'),
  output: {
    filename: `${pkg.name}.min.js`,
    path: path.resolve(rootPath, 'min'),
    library: `${pkg.name}`, // 模块名称
    libraryTarget: "umd" // 支持CommonJS、AMD, 全局对象
  },
  module: {
    rules: [{
        test: /\.js$/,
        loader: "babel-loader" // 处理js文件 Babel 是一个 JavaScript 编译器。(把浏览器不认识的语法,编译成浏览器认识的语法。)
    }]
  }
}

module.exports = config;

新建.babelrc文件:

{
  "presets":[
    ["@babel/preset-env",  {
      // 一般在webpack 项目中,我们会将此参数设置为false,既将module交由webpack处理,而不是babel。
      "modules": false 
    }]
  ],
  "plugins":[]
}

安装依赖

webpack 4.x | babel-loader 8.x | babel 7.x

npm install -D babel-loader @babel/core @babel/preset-env webpack@4 webpack-cli

安装好以后,就可以执行打包了:

"scripts": {
    "build": "webpack --config script/webpack.config.js",
  
  },

npm run build打包后,生产min/airspeed.min.js文件。打包后的结构大致如下:

airspeed(function webpackUniversalModuleDefinition(root, factory) {

if(typeof exports === 'object' && typeof module === 'object')

  module.exports = factory();

else if(typeof define === 'function' && define.amd)

  define([], factory);

else if(typeof exports === 'object')

  exports["airspeed"] = factory();

else

  root["airspeed"] = factory();

})(window, function() {

   return _entry_return_;

});

由上面代码可以看出,模块 支持CommonJS、AMD和全局对象。

意思就是,支持下面的几种方式引入:

CommonJS

cosnt airspeed= require("airspeed");

ES6

import airspeed from "airspeed";

AMD

require(['airspeed',], function (airspeed){
    // some code here
  });

全局对象

  <script src="airspeed.min.js"></script>
  <script>
      var OS = airspeed.getOS();
  </script>

 

配置按需引入模式

上文配置只是完成了打包,一般情况下到这里就可以直接发布到npm了,如果可以正常发布成功,就可以直接引入使用了。

但是如果我项目中只用到了一个函数,上面的方式引入会把整个工具包引入。怎么实现只引入我需要的函数呢?像这样引入:

const isEmptyObject = require("airspeed/isEmptyObject");

可以把src下面所有的js文件都复制到根目录下,发布的时候把根目录下的文件也发布上去,这样引入的时候就可以使用上面的方式了,使用哪个文件引入哪个就可以了。

script文件夹下增加两个文件:

build-copy.js

用来复制函数文件到根目录下:

const path = require('path')
const fs = require('fs')
const ora = require('ora')
const rm = require('rimraf')
const copy = require('copy')
const chalk = require('chalk')

const rootPath = path.resolve(__dirname, '../')

// 替换模块文件
let copying = ora('copying...')
copying.start()
rm('*.js', err => {
  if (err) throw (err)
  let folderList = fs.readdirSync(path.resolve(rootPath, 'src'))
  folderList.forEach((item, index) => {
    copy(`src/${item}/*.js`, rootPath, function (err, files) {
      if (err) throw err;
      if (index === folderList.length - 1) {
        console.log(chalk.cyan('  Copy complete.\n'))
        copying.stop()
      }
    })
  })
})

build-pack.js

这个文件就是用来打包的:

const path = require('path')
const ora = require('ora')
const rm = require('rimraf')
const chalk = require('chalk')
const webpack = require('webpack')

const config = require('./webpack.conf')
const pkg = require('../package.json')
const rootPath = path.resolve(__dirname, '../')

// 构建全量压缩包
let building = ora('building...')
building.start()
rm(path.resolve(rootPath, 'min', `${pkg.name}.min.js`), err => {
  if (err) throw (err)
  webpack(config, function (err, stats) {
    if (err) throw (err)
    building.stop()
    process.stdout.write(stats.toString({
      colors: true,
      modules: false,
      children: false,
      chunks: false,
      chunkModules: false
    }) + '\n\n')
    console.log(chalk.cyan('  Build complete.\n'))
  })
})

修改build.js文件:

require('./build-copy');
require('./build-pack');

修改package.json文件:

  "scripts": {
    "build": "node script/build.js",
    "build-copy": "node script/build-copy.js",
    "build-pack": "node script/build-pack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

安装依赖

cnpm i rimraf chalk ora copy -D

执行npm run build

这个过程如果有报错,降低模块的版本重试。打包后的文件如下:(my-outils后更名为airspeed)

发布

1 完善配置文件

npm忽略文件.npmignore:

src/
scripts/
node_modules/
.babelrc
.gitignore

git忽略文件:

node_modules/

发不到自己的git账号以后,修改package.json文件:

{
  "name": "airspeed",
  "version": "1.0.0",
  "description": "JavaScript utils",
  "main": "min/airspeed.min.js",
  "scripts": {
    "build": "node script/build.js",
    "build-copy": "node script/build-copy.js",
    "build-pack": "node script/build-pack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/artadmire/airspeed.git"
  },
  "keywords": [
    "outil",
    "tool",
    "common-util"
  ],
  "author": "MaiLe",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.17.0",
    "@babel/preset-env": "^7.16.11",
    "babel-loader": "^8.2.3",
    "chalk": "^4.1.2",
    "copy": "^0.3.2",
    "ora": "^5.4.1",
    "rimraf": "^3.0.2",
    "webpack": "^4.46.0",
    "webpack-cli": "^4.9.2"
  }
}

2 发布

2.1 npm账号

登陆npm账号,如果没有就注册一个。

2.2 npm adduser

使用 npm adduser命令来添加npm的账户名、密码和邮箱。

如果你使用的是淘宝镜像,切换回原镜像:npm config set registry https://registry.npmjs.org

2.3 npm login

这一步跟上面是一样的。

2.4 npm publish

如果没有报错说明发布成功了。

如果看下下面的报错,则需要验证邮箱。

在浏览器中登陆npm看到下面的提示:

根据提示,点击here一步一步完成邮箱验证就可以了。已经测似可以使用,如果验证过程会有些问题,就多尝试几次,结果可能有延迟。

验证好以后尝试重新登录。

工具包发布成功以后,引入试试看:

npm i airspeed -D
const isEmptyObject = require('airspeed/isEmptyObject')
isEmptyObject({}) 

node index.js文件 控制台输出true

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值