构建Npm模块

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-02-26

Npm 注册

# 注册
npm adduser

# 输入用户密码
Username: 

# 输入密码
Password: 

# 输入邮箱
Email: 

Npm登录和发布

# 登录 ps:第一次注册完成后自动登录
npm login

# 发布 
npm publish

发布的要求

  • 在每个模块根目录下都必须有一个描述该模块的package.json文件。该文件描述了模块的入口文件是哪个,该模块又依赖哪些模块等

  • 模块中的文件以JavaScript文件为主,且大多采用模块化规范。

写一个简单的模块发布上去

1.初始化

npm init
# 然后按要求输入生成package.json文件

2.创建入口文件 index.js

3.发布

# 如果你设置npm的镜像地址是淘宝镜像 ,那么要切回来才行
npm publish

4.安装使用这个发布的包

# 包名不能有大写字母/空格/下滑线
npm i packageName

5.删除包

# 如果报权限方面的错误 加上--force参数
npm unpublish packageName --force

接入webpack

问题:

  • 1、源代码采用ES6编写,但发布到Npm仓库时需要转换成ES5代码,并且遵守CommonJS模块化规范。如果发布到 Npm 上的ES5代码是经过转换的,则请同时提供Source Map以方便调试。

  • 2、组件依赖的其他资源文件如cssimg文件也需要包含在发布的模块里。

  • 3、尽量减少冗余代码,减少发布出去的组件的代码文件大小

  • 4、在发布出去的组件的代码中不能含有其依赖的模块的代码,而是让用户可选择性地安装。例如不能内嵌React库的代码,这样做的目的是,在其他组件也依赖React库时,防止React库的代码被重复打包。

解决:(具体实施见下面代码示例)

针对问题1:

  • 使用babel-loaderES6 代码转换成ES5代码。
  • 开启devtool: 'source-map'输出 Source Map以供调试。
  • 设置output.libraryTarget ='commonjs2',使输出的代码符合CommonJS2模块化规范,以供其他模块导入使用。

针对问题2:

  • 配置cssloaderextract-text-webpack-plugin实现。

针对问题3:

  • 需要注意的是 Babel在将 ES6代码转换成ES5代码时会注入一些辅助函数。参考使用ES6

针对问题4:

  • 配置externals,来告诉在Webpack 要构建的代码中使用了哪些不用被打包的模块,也就是说这些模板是外部环境提供的, Webpack 在打包时可以忽略它们。

代码示例

Webpakc的配置文件:

// webpack.config.js
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  // 模块的入口文件
  entry: './src/index.js',
  output: {
    // 输出文件的名称
    filename: 'index.js',
    // 输出文件的存放目录 放到lib/index.js供别人引入
    path: path.resolve(__dirname, 'lib'),
    // 输出的代码符合 CommonJS 模块化规范,以供给其它模块导入使用。
    libraryTarget: 'commonjs2',
  },
  externals: /^(react|babel-runtime)/,
  // 通过正则命中所有以 react 或者 babel-runtime 开头的模块
  // 这些模块使用外部的,源码不能被打包进输出的代码里
  // 但是会在打包好的代码中require进去
  // 
  // 
  // [
  //   (function (module, exports) {
  //     module.exports= require ("babel-runtime/helpers/inherits");
  //     } ) ,
  //   (function (module, exports) {
  //     module.exports= require ("react");
  //   })
  // ]
  module: {
    rules: [
      {
        test: /\.js$/,
        use: ['babel-loader'],
        // 排除 node_modules 目录下的文件
        // node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
        exclude: path.resolve(__dirname, 'node_modules'),
      },
      {
        // 增加对 CSS 文件的支持
        test: /\.css/,
        // 提取出 Chunk 中的 CSS 代码到单独的文件中
        use: ExtractTextPlugin.extract({
          use: ['css-loader']
        }),
      },
    ]
  },
  plugins: [
    new ExtractTextPlugin({
      // 输出的 CSS 文件名称
      filename: 'index.css',
    }),
  ],
  // 输出 Source Map
  devtool: 'source-map',
};

Babel配置文件

// .babelrc
{
  "plugins": [
    [
      "transform-runtime",
      {
        "polyfill": false
      }
    ]
  ],
  "presets": [
    "env",
    "react"
  ]
}

package.json指定入口

{
  "name": "hello-webpack",
  "main": "lib/index.js", // 别人引入的时候引入的代码
  "jsnext:main": "src/index.js", // 指出采用ES6编写的模块入口所在的位置
}

src/index.js功能模块

import React, { Component } from 'react';
import './index.css';

// 导出该组件供给其它模块使用
export default class HelloWebpack extends Component {
  render() {
    return <h1 className="hello-component">Hello,Webpack</h1>
  }
}

src/index.css模块使用的css文件

.hello-component {
  color: lawngreen;
  background-color: black;
}
使用这个发布的包
import React from 'react';
import { render } from 'react-dom';
import HelloWebpack from 'hello-webpack';
import 'hello-webpack/lib/index.css';

render(<HelloWebpack/>, window.document.getElementById('app'));

代码示例2:最简单的Npm包的发布流程

test/index.js 功能代码:

exports.sum = function () {
  var result = 0;
  for(var i = 0 ; i < arguments.length ; i++) {
    result += arguments[i]
  }
  return result;
}

test/package.json包配置:

{
  "name": "npm-test-cz",
  "version": "0.0.1",
  "description": "test package",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "11",
    "22"
  ],
  "author": "upcccz",
  "license": "ISC"
}

test目录下使用命令npm publish就能发布这个包了(需要先登录Npm,参考上面的Npm注册Npm登录

使用npm-test-cz这个包:Npm对应仓库

# 安装
npm i npm-test-cz
const testModule = require('npm-test-cz');
console.log(testModule.sum(1,2,3,4)); // 10