构建工具
Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。Rollup 对代码模块使用新的标准化格式,这些标准都包含在 JavaScript 的 ES6 版本中,而不是以前的特殊解决方案,如 CommonJS 和 AMD。ES6 模块可以使你自由、无缝地使用你最喜爱的 library 中那些最有用独立函数,而你的项目不必携带其他未使用的代码。ES6 模块最终还是要由浏览器原生实现,但当前 Rollup 可以使你提前体验。所以我们采用rollup做为我们的构建工具。
Rollup中文网
安装 rollup:npm i rollup -g
代码仓库
可以将代码托管在github或者码云等远程仓库上
初始化项目
将新建的远程仓库拉去到本地后,就要开始执行初始化项目了
-
首先执行
npm init -y
生成package.json
文件; -
安装依赖
安装rollup:pnpm add rollup
安装rollup的插件:pnpm add @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-typescript
插件说明:
@rollup/plugin-commonjs:rollup本身是不支持CommonJS的,使用了这个插件,就可以解析CommonJS模块了
@rollup/plugin-node-resolve:rollup 无法识别 node_modules 中的包,帮助 rollup 查找外部模块,然后导入
@rollup/plugin-typescript:rollup中使用typescript必备的插件 -
在安装@rollup/plugin-typescript插件时提示我们需要tslib和typescript,所以还要安装另外两个第三方库:
pnpm add tslib typescript
; -
安装代码压缩和清除注释插件:
pnpm add rollup-plugin-terser rollup-plugin-cleanup
;
rollup-plugin-terser插件用于代码压缩
rollup-plugin-cleanup插件用于去除无效代码 -
配置typescript:
在终端中执行npx tsc --init
命令,生成tsconfig.json
文件
修改tsconfig.json文件如下:{ "compilerOptions": { "baseUrl": ".", "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "downlevelIteration": true, // 是否自动创建类型声明文件 "declaration": true, // 类型声明文件的输出目录 "declarationDir": "dist/types", // 只生成声明文件,而不会生成js文件 "emitDeclarationOnly": true, // 指定输出文件目录(用于输出),用于控制输出目录结构 "rootDir": "src", "paths": { "@/*": ["src/*"], "@types/*": ["src/types/*"], "@utils/*": ["src/utils/*"] } }, "include": ["src"], }
-
配置rollup:在根目录下新建文件
rollup.config.js
import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import typescript from '@rollup/plugin-typescript'; import { terser } from 'rollup-plugin-terser'; import cleanup from 'rollup-plugin-cleanup'; export default [ { input: './src/index.ts', output: { dir: 'dist', format: 'cjs', entryFileNames: '[name].cjs.js', }, plugins: [resolve(), commonjs(), typescript(), terser(), cleanup()], }, { input: './src/index.ts', output: { dir: 'dist', format: 'esm', entryFileNames: '[name].esm.js', }, plugins: [resolve(), commonjs(), typescript(), terser(), cleanup()], } ];
-
书写工具函数代码:
在根目录下新建src目录,在src目录下新建index.ts
编写我们的工具函数import SlsTracker from '@aliyun-sls/web-track-browser'; const opts = { host: 'cn-hangzhou.log.aliyuncs.com', // 所在地域的服务入口。例如cn-hangzhou.log.aliyuncs.com project: 'aliyun-log', // Project名称。 logstore: 'logstore', // Logstore名称。 time: 10, // 发送日志的时间间隔,默认是10秒。 count: 10, // 发送日志的数量大小,默认是10条。 topic: 'topic',// 自定义日志主题。 source: 'source', tags: { tags: 'tags', }, } const tracker = new SlsTracker(opts) //上传单条日志 export const sendLog = (obj: Object) => { console.log('sendLog=>', obj) tracker.send(obj) } // 立即上传单条日志。此时配置time和count参数不生效。 export const sendLogImmediate = (obj: Object) => { console.log('sendLogImmediate=>', obj) tracker.sendImmediate(obj) } // 批量上传日志。 export const sendBatchLogs = (arr: Array<Object>) => { console.log('sendBatchLogs=>', arr) tracker.sendBatchLogs(arr) } // 批量上传日志。此时配置time和count参数不生效 export const sendBatchLogsImmediate = (arr: Array<Object>) => { console.log('sendBatchLogsImmediate=>', arr) tracker.sendBatchLogsImmediate(arr) }
-
【解决SyntaxError: Cannot use import statement outside a module问题】
在导入相关js文件后,出现 Cannot use import statement outside a module错误,
报错是因为node环境不支持ES6语法,我们可以安装babel-jest、@babel/core、@babel/preset-env来解决问题(这几个插件可以将es6代码转换成es5,使node环境能够识别,这里我选择的是@babel/preset-env进行安装)
安装完后,在项目根木录创建babel.config.js文件:这个文件见名知意,是对babel进行配置的;(类似的还有webpack.config.js),module.exports = { "presets": [ ["@babel/preset-env", { "targets": { "node": true } } ] ] }
一般来说package.json是没有配置type的,给它配上type:type:“module”.到这里问题就解决了
-
完善package.json配置
{ "name": "aliyun-log", "version": "1.0.1", "description": "aliyun log", "main": "./dist/index.cjs.js", "module": "./dist/index.esm.js", "types": "./dist/types/index.d.ts", "type": "module", "files": [ "dist" ], "scripts": { "dev": "rollup -w -c", "build:types": "tsc -b ./tsconfig.json", "build": "npm run build:types && rollup -c", "prepublish": "pnpm version && pnpm build" }, "keywords": [ "utils" ], "author": "fengzhao", "license": "MIT", "publishConfig": { "access": "public" }, "dependencies": { "@aliyun-sls/web-track-browser": "^0.0.3", "@babel/preset-env": "^7.20.2", "@rollup/plugin-commonjs": "^23.0.2", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-typescript": "^9.0.2", "rollup": "^3.2.5", "rollup-plugin-cleanup": "^3.2.1", "rollup-plugin-terser": "^7.0.2", "tslib": "^2.4.1", "typescript": "^4.8.4" } }
“types”: "./dist/types/index.d.ts"的作用:
仅仅是生成了类型声明文件还不行,外部在引用该工具库的时候还是无法找到模块的声明文件。若要彻底解决这个问题,可以在 package.json 中配置 types 属性,将其指向生成的类型声明文件。
如果发布公有包需要在package.json中增加publishConfig的配置"publishConfig": { "access": "public" },
-
执行打包:
pnpm build打包文件后会发现在根目录下生成了dist文件夹
-
npm账号注册:注册网址,根据提示进行账号注册即可。
-
npm登录:
执行npm login命令之前,首先切换到npm源,如果是淘宝源或者其他源会报错。
查询镜像源:npm get registry
切换到npm:npm config set registry https://registry.npmjs.org
切换到淘宝:npm config set registry https://registry.npm.taobao.org
通过配置淘宝镜像并使用cnpm安装:npm install -g cnpm --registry=https://registry.npm.taobao.org
登录成功提示: -
npm发布
登录成功后执行npm publish
;
发布成功提示:
npm上成功展示刚刚上传的包
-
修改npm包
更新代码,修改package.json文件的version版本号,保存后上传到远程,再执行npm publish
; -
删除npm包:
npm unpublish <包名> -force
; -
使用npm包:在使用的项目里执行
npm install <包名> --save
;
在需要的文件里引入依赖即可:import { 函数名 } from ‘包名’;