我的第一个 package

445

问,制作一个 package,总共需要几步? 答:三步。

前言

是的,这是一个孔子看了想打人,诸葛看了要骂街的答案。正经一点儿说,制作一个包里面的细节还是不少的。要求一个作者对 JavaScript 模块化有基本的认识,不只是像我一样只熟悉 AMD, CMD, commonJS 的拼写。最起码要知道它们之间的区别和使用场景。其中,commonJS 是 node 服务端使用的,在浏览器中并不支持,前端可能会陌生。我们简单区分一下:module.exports/requireexport/import 分别是 node 和 ES 6 使用的规范。

起个名字

要制作一个 package 是要从 npm init 开始的。输入这个命令后,会有一个交互式的问答操作,生成一份简单的 package.json, 里面包含一些基本信息。然后,需要注册一个npm账号,使用 npm login 来执行登陆操作。起名字是个简单而又愉快的过程,接下来的制作,可就要花点心思了。

如何制作

1.目录结构

  • dist
  • doc
  • src
  • test

package 目录的结构大致如此,按照需求来区分。我们需要一个用来编写 package 的源码目录 src。需要一个打包生成的目录,供其他人调用 dist,注意,这个dist的目录也要在根目录的 package.json 中设置 main.js 属性。需要一个目录来管理文档说明,指引其他人如何使用,这就是 doc 目录,这个目录实际上是一个独立的子 package,它包含自己独立的 webpack.config.js,因为它经过 webpack 打包生成的文档包含 html 文件,不只是一个供用户 import 的 package。

2.webpack 配置

talk is cheap, show me your code. 说话是便宜的,看我你的代码。(这个直译辣不辣眼镜)。接下来,打算在下面的实际配置中通过具体添加注释来说明

module.exports = {
  // 一定要使用 production 的配置项,因为这个包生成的文件是给其他用户使用的,production 提供了基本的压缩优化功能,以及其他一些不同的默认设置。
  "mode": "production",
  // 就是我们的源码目录没什么多说的
  "entry": "./src/index.js",
  // 这里需要自定义
  "output": {
    "path": __dirname + '/dist',
    "filename": "[name].js",
    // 这里推荐使用 umd,毕竟考虑用户会用 require 和 import 两种方式导入我们的包
    "libraryTarget": "umd"
  },
  "module": {
    // 惯例配置,无需多言
    "rules": [
      {
        "test": /\.(js|jsx)$/,
        "exclude": /node_modules/,
        "use": {
          "loader": "babel-loader",
        }
      }
    ]
  },
  externals: {
    // 这里要格外注意,我的这个包基于 react 组件开发。这里不需要包 react 打包进去,一个是因为体积,另外用户一定要有 react 环境才能正常使用我们的包。
    'react': "react"
  }

}

3.文档编写

前面提到文档编写的包其实是一个独立的 package,这里也把配置代码贴了出来。主要不同在于有 devsever 和 htmlWebpackPlugin。

var path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'development',
  entry: "./src/index.js",
  output: {
    filename: "index-bundle.js"
  },
  "module": {
    "rules": [
      {
        "test": /\.(js|jsx)$/,
        "exclude": /node_modules/,
        "use": {
          "loader": "babel-loader",
        }
      }
    ]
  },
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000,
    //module: false
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "doc.html",
      template: "./src/index.html"
    })
  ]
};

4.gitignore 和 .npmignore 等其他设置

Keeping files out of your package

Use a .npmignore file to keep stuff out of your package. If there’s no .npmignore file, but there is a .gitignore file, then npm will ignore the stuff matched by the .gitignore file. If you want to include something that is excluded by your .gitignore file, you can create an empty .npmignore file to override it. Like git, npm looks for .npmignore and .gitignore files in all subdirectories of your package, not only the root directory.

我们可以通过上述文档知道一件事, npmignore 比 gitignore 的优先级高。

5.(误)其他重要的事

持续集成是开发一个包所必备的,因为我还没有具体实践,这里就挖坑不表了。

参考资料

pic