一、npm publish
發布包到npm庫的命令是npm publish
npm publish發布包,需要先配置webpack.json文件,如果沒有webpack.json文件,可以通過npm init命令初始化一個
package.json的部分字段簡介如下
name:發布的包名,默認是上級文件夾名。不得與現在npm中的包名重復。包名不能有大寫字母/空格/下滑線! version:你這個包的版本,默認是1.0.0。對於npm包的版本號有着一系列的規則,模塊的版本號采用X.Y.Z的格式,具體體現為: 1、修復bug,小改動,增加z。 2、增加新特性,可向后兼容,增加y 3、有很大的改動,無法向下兼容,增加x description:項目簡介 mian:入口文件,默認是index.js scripts:包含各種腳本執行命令 test:測試命令。 author:自己的賬號名 license:開源文件協議 private:是否私有
如果要發布的話需要把private字段設為false
發布的包的資源可以通過https://unpkg.com/$name@$version/找到。
比如我發布了一個包,name是zxz-ui,version是1.0.0,那么我就可以在 https://unpkg.com/zxz-ui@1.0.0/ 找到我發布的包里面的資源
我們可以通過創建文件npmignore或者 pkg.files來設置上傳時過濾某些文件和文件夾,如果我們不設置的話,有些文件和文件夾也是會默認忽略上傳的,比如node_modules文件夾、package-lock.json文件等
二、我們如何通過npm引用組件的
先看一下node.js中的模塊調用的規則 https://nodejs.org/api/modules.html#modules_accessing_the_main_module
主要注意以下兩部分
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.js的webpack配置文件
https://github.com/iview/iview/blob/2.0/build/webpack.dist.dev.config.js
…… process.env.NODE_ENV = 'production'; module.exports = merge(webpackBaseConfig, { devtool: 'source-map', entry: { main: './src/index.js' }, output: { path: path.resolve(__dirname, '../dist'), publicPath: '/dist/', filename: 'iview.js', library: 'iview', libraryTarget: 'umd', umdNamedDefine: true }, …… });
上面是在生產環節下打包iview.js的配置,我們找到它的入口文件
https://github.com/iview/iview/blob/2.0/src/index.js
import Affix from './components/affix'; …… const components = { Affix, …… }; const iview = { ...components, iButton: Button, …… }; const install = function(Vue, opts = {}) { if (install.installed) return; …… Object.keys(iview).forEach(key => { Vue.component(key, iview[key]); }); …… }; // auto install if (typeof window !== 'undefined' && window.Vue) { install(window.Vue); } const API = { …… install, …… }; …… module.exports.default = module.exports = API; // eslint-disable-line no-undef
這里說明一下,我是用組件內部的name屬性做的組件標簽名
5. 配置webpack.config.js
var path = require('path') var webpack = require('webpack') const NODE_ENV = process.env.NODE_ENV module.exports = { //入口這里一個是測試組件時npm run dev的入口文件,一個是npm run build的入口文件 entry: NODE_ENV === 'development' ? './src/main.js' : './index.js', output: { path: path.resolve(__dirname, './dist'), publicPath: '/dist/', //輸出的文件夾 filename: 'filename.js',//輸出的文件名 library: 'objectname', //引用js文件時創建的全局變量名 libraryTarget: 'umd', umdNamedDefine: true }, …… }
……
20
配置package.json
{ "name": "package-name", "description": "描述", "version": "1.0.0", "author": "XXXXXXXXXXX", "license": "MIT", "private": false, "main": "dist/filename.js", …… }
npm run build npm publish 使用 //npm導入 npm i package-name import xxx from 'package-name' Vue.use(xxx)
//cdn導入
<script src="//vuejs.org/js/vue.min.js"></script> <script src="//https://unpkg.com/package-name@1.0.0/dist/filename.js"></script>
如果想把css單獨抽離出來還需要更新webpack、webpack-cli,和安裝optimize-css-assets-webpack-plugin、uglifyjs-webpack-plugin等包。
webpack配置:https://github.com/pma934/zxz-ui/blob/master/webpack.config.js