极客时间对于推广渠道会有返利优惠,比如山月在极客时间买了一门课,再把课程分享给好友购买,这时极客时间会向山月返利20元左右。
而我现在做了一个返利平台,你可以在上边通过山月的链接购买课程,此时极客时间会向我返利。为了共同学习,而你可以添加我的微信 (shanyue94),我将把极客时间给我的返利发一个红包全部返给你

# name、version 与 semver 字段

nameversion 字段几乎是

# main、exports、module

# main

main 指 npm package 的入口文件,当我们对某个 package 进行导入时,实际上导入的是 main 字段所指向的文件。

main 是 CommonJS 时代的产物,也是最古老且最常用的入口文件。

// package.json 内容
{
  name: 'midash',
  main: './dist/index.js'
}

// 关于如何引用 package
const midash = require('midash')

// 实际上是通过 main 字段来找到入口文件,等同于该引用
const midash = require('midash/dist/index.js')

# module

随着 ESM 且打包工具的发展,许多 package 会打包 N 份模块化格式进行分发,如 antd 既支持 ES,也支持 umd,将会打包两份。

antd 分发了两种格式

如果使用 import 对该库进行导入,则首次寻找 module 字段引入,否则引入 main 字段。

基于此,许多前端友好的库,都进行了以下分发操作:

  1. 对代码进行两份格式打包: commonjses module
  2. module 字段作为 es module 入口
  3. main 字段作为 commonjs 入口
{
  name: 'midash',
  main: './dist/index.js',
  module: './dist/index.mjs'
}

// 以下两者等同
import midash from 'midash'
import midash from 'midash/dist/index.mjs'

如果你的代码只分发一份 es module 模块化方案,则直接置于 main 字段之中。

# exports

如果说以上两个是刀剑,那 exports 至少得是瑞士军刀。

exports 可以更容易地控制子目录的访问路径,也被称为 export map

假设我们 Package 的目录如下所示:

├── package.json
├── index.js
└── src
    └── get.js

不在 exports 字段中的模块,即使直接访问路径,也无法引用!

// package.json
{
  name: 'midash',
  main: './index.js',
  exports: {
    '.': './dist/index.js',
    'get': './dist/get.js'
  }
}

// 正常工作
import get from 'midash/get'

// 无法正常工作,无法引入
import get from 'midash/dist/get'

exports 不仅可根据模块化方案不同选择不同的入口文件,还可以根据环境变量(NODE_ENV)、运行环境(nodejs/browser/electron) 导入不同的入口文件。

{
  "type": "module",
  "exports": {
    "electron": {
      "node": {
        "development": {
          "module": "./index-electron-node-with-devtools.js",
          "import": "./wrapper-electron-node-with-devtools.js",
          "require": "./index-electron-node-with-devtools.cjs"
        },
        "production": {
          "module": "./index-electron-node-optimized.js",
          "import": "./wrapper-electron-node-optimized.js",
          "require": "./index-electron-node-optimized.cjs"
        },
        "default": "./wrapper-electron-node-process-env.cjs"
      },
      "development": "./index-electron-with-devtools.js",
      "production": "./index-electron-optimized.js",
      "default": "./index-electron-optimized.js"
    },
    "node": {
      "development": {
        "module": "./index-node-with-devtools.js",
        "import": "./wrapper-node-with-devtools.js",
        "require": "./index-node-with-devtools.cjs"
      },
      "production": {
        "module": "./index-node-optimized.js",
        "import": "./wrapper-node-optimized.js",
        "require": "./index-node-optimized.cjs"
      },
      "default": "./wrapper-node-process-env.cjs"
    },
    "development": "./index-with-devtools.js",
    "production": "./index-optimized.js",
    "default": "./index-optimized.js"
  }
}

# NPM Script 的生命周期

在 npm 中,使用 npm scripts 可以组织整个前端工程的工具链。

{
  start: 'serve ./dist',
  build: 'webpack',
  lint: 'eslint'
}

除了可自定义 npm script 外,npm 附带许多内置 scripts

npm install

npm test

npm publish
  1. 在某个 npm 库安装结束后,自动执行操作如何处理?
  2. npm publish 发布 npm 库时将发布打包后文件,如果遗漏了打包过程如何处理,如何在发布前自动打包?

这就要涉及到一个 npm script 的生命周期

# 一个 npm script 的生命周期

当我们执行任意 npm run 脚本时,将自动触发 pre/post 的生命周期。

当手动执行 npm run abc 时,将在此之前自动执行 npm run preabc,在此之后自动执行 npm run postabc

// 自动执行
npm run preabc

npm run abc

// 自动执行
npm run postabc

patch-package (opens new window) 一般会放到 postinstall 中。

{
  postinstall: 'patch-package'
}

而发包的生命周期更为复杂,当执行 npm publish,将自动执行以下脚本。

  • prepublishOnly: 最重要的一个生命周期。
  • prepack
  • prepare
  • postpack
  • publish
  • postpublish

当然你无需完全记住所有的生命周期,如果你需要在发包之前自动做一些事情,如测试、构建等,请在 prepulishOnly 中完成。

{
  prepublishOnly: 'npm run test && npm run build'
}

# 一个最常用的生命周期

prepare

  1. npm install 之后自动执行
  2. npm publish 之前自动执行

比如 husky

{
  prepare: 'husky install'
}

关于山月

我的项目:
我的微信:shanyue94,欢迎交流
Last Updated: 7/21/2019, 11:25:08 AM