require(X) from module at path Y
1. If X is a core module,
a. return the core module
b. STOP
2. If X begins with '/'
a. set Y to be the filesystem root
3. If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
4. LOAD_NODE_MODULES(X, dirname(Y))
5. THROW "not found"
LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text. STOP
2. If X.js is a file, load X.js as JavaScript text. STOP
3. If X.json is a file, parse X.json to a JavaScript Object. STOP
4. If X.node is a file, load X.node as binary addon. STOP
LOAD_INDEX(X)
1. If X/index.js is a file, load X/index.js as JavaScript text. STOP
2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
3. If X/index.node is a file, load X/index.node as binary addon. STOP
LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
a. Parse X/package.json, and look for "main" field.
b. If "main" is a falsy value, GOTO 2.
c. let M = X + (json main field)
d. LOAD_AS_FILE(M)
e. LOAD_INDEX(M)
f. LOAD_INDEX(X) DEPRECATED
g. THROW "not found"
2. LOAD_INDEX(X)
LOAD_NODE_MODULES(X, START)
1. let DIRS = NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
a. LOAD_AS_FILE(DIR/X)
b. LOAD_AS_DIRECTORY(DIR/X)
NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = [GLOBAL_FOLDERS]
4. while I >= 0,
a. if PARTS[I] = "node_modules" CONTINUE
b. DIR = path join(PARTS[0 .. I] + "node_modules")
c. DIRS = DIRS + DIR
d. let I = I - 1
5. return DIRS
以iview为例,我们npm i iview下载iview组件库后,通过import iView from 'iview'引用它,其实就是通过import iView from './node_modules/iview'引用它,然后./node_modules/iview是一个文件夹,会按照LOAD_AS_DIRECTORY(X)中的规则寻找,先是找到./node_modules/iview/package.json这个文件,然后找到其中的main字段,最后通过main字段找到./node_modules/iview/dist/iview.js这个文件。
iview.js这个文件是通过webpack打包得到的,直接看代码基本上是看不懂的,我们看看它是怎么打包出来的。
主要是参考了一下这篇教程还有iview和element这两个组件库的package.json、index.js、webpack文件。
只看创建流程可以直接看第三部分
一、npm publish
发布包到npm库的命令是
npm publish
npm publish
发布包,需要先配置webpack.json
文件,如果没有webpack.json
文件,可以通过npm init
命令初始化一个package.json
的部分字段简介如下如果要发布的话需要把private字段设为false
发布的包的资源可以通过
https://unpkg.com/$name@$version/
找到。我们可以通过创建文件
npmignore
或者pkg.files
来设置上传时过滤某些文件和文件夹,如果我们不设置的话,有些文件和文件夹也是会默认忽略上传的,比如node_modules文件夹、package-lock.json文件等二、我们如何通过npm引用组件的
先看一下node.js中的模块调用的规则 https://nodejs.org/api/modules.html#modules_accessing_the_main_module
主要注意以下两部分
以iview为例,我们
npm i iview
下载iview组件库后,通过import iView from 'iview'
引用它,其实就是通过import iView from './node_modules/iview'
引用它,然后./node_modules/iview
是一个文件夹,会按照LOAD_AS_DIRECTORY(X)
中的规则寻找,先是找到./node_modules/iview/package.json
这个文件,然后找到其中的main
字段,最后通过main
字段找到./node_modules/iview/dist/iview.js
这个文件。iview.js
这个文件是通过webpack打包得到的,直接看代码基本上是看不懂的,我们看看它是怎么打包出来的。先找到iview.js的webpack配置文件
https://github.com/iview/iview/blob/2.0/build/webpack.dist.dev.config.js
上面是在生产环节下打包iview.js的配置,我们找到它的入口文件
https://github.com/iview/iview/blob/2.0/src/index.js
从该文件可以看出来,它先是将components文件夹中的组件都通过import引入,然后定义了一个components对象来存放所有组件,然后又对部分组件增加了第二个key定义了iview对象(例如
<Col><Col>
组件,也可以通过<i-col><i-col>
来使用),然后定义了一个install函数来遍历注册组件。最后将install函数作为输出对象的install方法。然后这个输出对象其实就是上面
import iView from 'iview'
得到的iView
对象,因此通过Vue.use(iView)
来调用iView.install
方法就能成功的把iView库的组件注册到我们的Vue对象上。另外,如果是直接通过CDN引用js文件的话,会触发auto install注释下的内容,会将组件注册到当前
window.Vue
上(需要先通过CDN引入vue.js)三、流程
这里说明一下,我是用组件内部的name属性做的组件标签名
webpack.config.js
package.json