本文基于cesium封装sdk,旨在构建一个集成webpack+ts+react的sdk模板,封装部分工具后,将发布于npm。工具比较简单(工具内容将在github持续更新),重在梳理搭建和发布的流程。
一、搭建sdk模板
技术栈选择:webpack 5.X:sdk打包工具;react 17.X:用于开发测试sdk功能的页面;typescript:检测类型,非常适合sdk开发。
1、初始化项目
npm init // 按提示填写,可先不配置git地址
2、安装typescript和react、react-dom及其Ts类型。
npm i typescript react react-dom
npm i @types/react @types/react-dom --save-dev
3、初始化tsconfig.json配置文件
tsc --init
此时根目录下已生成tsconfig.json,参考配置:【compilerOptions配置项手册】
{
"compilerOptions": {
"outDir": "./dist/", //指定输出文件夹
"sourceMap": true, //编译时是否生成.map文件
"removeComments": true, //删除所有注释,除了以 /!*开头的版权信息。
"noImplicitAny": true, // 没有为值设置明确的类型时,设为false:编译器会默认认为值为any,设为true:报错
"module": "es6", //编译后的js要使用的模块标准
"declaration": true, // 是否生成 .d.ts声明文件
"declarationDir": "./dist/types/", // 声明文件打包的位置
"target": "es5", //编译后的js应遵循的js版本
"jsx": "react", //使用前不许转换,输出文件扩展名.js
"allowJs": true, //是否允许编译js文件
"allowSyntheticDefaultImports": true, //允许模块默认导入
"esModuleInterop": true, //未导入内容创建空间命名,实现commonjs和es模块的互操作性
"moduleResolution": "node", //模块解析策略:node/classic
},
"include": ["./src/**/*","./index.ts","./typings.d.ts"], //指定编译的路径,支持文件夹、通配符等
"exclude": ["node_modules"], //要排除的,不编译的文件,规则同include
}
4、创建目录结构
根目录下创建src、test两个文件夹。
src内放置sdk封装的工具。test内放置测试sdk方法的页面(使用react编写),新建test/index.tsx配置React的DOM入口节点;新建test/App.tsx作为React主页面;新建test/public/index.html作为html主页面。- 根目录下新建
index.ts文件,作为sdk工具的export文件。 index.ts:
export { Map } from "./src/Map"; //方法导出示例。
test/index.tsx
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import "./assets/widgets.css"; //Cesium的样式文件
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root"));
test/App.tsx
import React from "react";
export default function App() {
return (
<div>Hello!!!!</div>
);
}
test/public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<link rel="shortcut icon" href="#" />
<!-- 若引用本地文件,可将Cesium.js放在 /test/public文件夹,webpack.config.dev.js中 devServer.contentBase内配置:
<script src="./Cesium.js" type="text/javascript"></script> -->
<script src="http://www.supermapol.com/earth/Build/Cesium/Cesium.js"></script>
<title>cesium-sdk 测试</title>
</head>
<body>
<div id="root"></div>
<div id="map"></div>
</body>
</html>
5、安装webpack
npm i webpack --save-dev
npm i webpack-cli@3.3.12 --save-dev
npm i webpack-dev-server@3.11.2 --save-dev
npm i html-webpack-plugin clean-webpack-plugin --save-dev
webpack-cli:cli(Command Line Interface),用于命令行中运行webpack。要想兼容老版本的命令:在使用webpack4.X及以上版本时,可搭配3.X版本的webpack-cli。webpack-dev-server:用于webpack开发环境,使用3.X版本(理由同上)。功能:为静态文件提供web服务;自动(局部)刷新。html-webpack-plugin:该插件会在html文件内新建script标签,并引入所有webpack生成的打包文件。clean-webpack-plugin:用于重新打包时,清空打包文件夹内原来的文件。
6、选择webpack转译typescript的方案
本文使用ts-loader+babel-loader+fork-ts-checker-webpack-plugin的方案,转译typescript。
Webpack 转译 Typescript 现有方案。
npm i ts-loader babel-loader fork-ts-checker-webpack-plugin --save-dev
npm i @babel/core --save-dev
ts-loader:webpack 的 TypeScript 加载器。babel-loader:允许使用 babel 和 webpack 编译.js文件。fork-ts-checker-webpack-plugin:在单独的进程上运行 TypeScript 类型检查器的 Webpack 插件。@babel/core:Babel 编译器核心。
7、安装style相关加载器(css、less、png等)
主要用于react测试页面的:
npm i css-loader style-loader less-loader url-loader --save-dev
8、webpack配置文件
本文封装的sdk以工具类为主,因此开发模式下只需要编译React编写sdk测试页面,生产环境下只编译(打包)src目录下的工具类。
根目录下新建webpack配置文件:webpack.config.js 配置项手册
webpack.config.dev.js【开发模式:/test/index.tsx作为入口文件】webpack.config.js【生产模式:/index.ts作为入口文件】
webpack.config.dev.js:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
module.exports = {
// development:会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 development。
mode: "development",
entry: "./test/index.tsx",
//devtool: "source-map"可build代码,但是速度最慢。
devServer: {
hot: true, //热模块:仅更新更改内容;修改js/css后,立即更新浏览器
contentBase: path.join(__dirname, "./test/public"), //告诉服务器从哪里提供内容
},
module: {
//创建模块时,匹配请求的规则数组。
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
"babel-loader",
{
loader: "ts-loader",
options: {
// 关闭ts类型检查,只进行转译。使用fork-ts-checker-webpack-plugin做类型检查。
transpileOnly: true,
},
},
],
},
{
test: /\.less$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{
loader: "less-loader",
options: {
lessOptions: {
javascriptEnabled: true, //支持内联js
},
},
},
],
},
{
test: /\.css$/,
use: [{ loader: "style-loader" }, { loader: "css-loader" }],
},
{
test: /\.(png|jpg|gif|svg|jpeg)$/,
use: [
{
loader: "url-loader",
options: {
limit: 1000240, //图片大小限制
},
},
],
},
],
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx", ".json"],
//按顺序解析后缀名。生产模式下可以不配置.tsx、.jsx。
},
plugins: [
new HtmlWebpackPlugin({
template: "./test/public/index.html",
}),
new ForkTsCheckerWebpackPlugin({
typescript: {
diagnosticOptions: {
syntactic: true, //语法检查
semantic: true, //语义检查
declaration: true, //声明检查
global: true, //全局
},
},
}),
],
};
webpack.config.js:
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
// production:会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 production。
mode: "production",
entry: "./index.ts",
output: {
path: path.resolve(__dirname, "dist"), //输出目录对应绝对路径; '/dist'
filename: "cesium-sdk.min.js", //决定bundle输出名称
library: {
type: "module", //同output.libraryTarget, 配置如何暴露library(影响打包文件的导出方式:变量/对象/模块)
},
// umdNamedDefine: true, //当library.type为'umd'时,umdNamedDefine为true,将命名由umd构建的amd模块
},
experiments: {
outputModule: true, //library.type设置为'module'时,需要启用该项(webpack5供用户启用的实验性特性)
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
"babel-loader",
{
loader: "ts-loader",
// 生产环境,可以选择保留声明文件,不设置transpileOnly
},
],
},
//.less .css 和 图片的 rules 配置 同上。
...
],
},
resolve: {
extensions: [".ts", ".js", ".json"], //可以只选择需要解析的文件类型
},
plugins: [new CleanWebpackPlugin()],
};
9、集成webpack配置(package.json)
在package.json文件原有配置基础上,添加以下options:package.json配置项手册
"main": "./dist/cesium-sdk.min.js", //程序的主要入口点。使用该包时,将进入的文件。
"types": "./dist/types/index.d.ts", //指定主声明文件(可选),此为ts的配置
"files": ["dist"], //当包作为依赖项安装时,需要包含的条目
"scripts": {
"dev": "webpack-dev-server --config webpack.config.dev.js", //开发模式运行命令
"build": "webpack --config webpack.config.js" //生产模式运行命令
},
此时已完成sdk模板的配置,npm run dev查看测试页面效果。查看完整代码
二、上传npm
如果本地使用,直接在package.json的依赖中配置git仓库地址即可,这样方便调试,避免频繁更新npm包。
- 准备工作:需要在npm官网注册账户。
1、项目根目录下,执行npm登陆命令
npm login
// ... 按提示输入用户名、密码、邮箱
npm who am i // 可验证登陆是否成功
- 注:如果之前配置过淘宝镜像,这一步可能会报错
500 Internal Server Error - PUT https://registry.npm.taobao.org...解决方案:
npm config set registry https://registry.npmjs.org/ //切回npm.js源
curl https://registry.npmjs.org/ //检查地址
npm cache clean --force //清除缓存
2、发布npm包
npm publish //每次publish 都要注意package.json里的version不要和上次相同
- 注:发布时若403报错
403 Forbidden - PUT https://registry.npmjs.org/cesium-sdk - Forbidden
403 In most cases, you or one of your dependencies are requesting
403 a package version that is forbidden by your security policy.
可能导致原因:
- 包名/版本号冲突。可在package.json内修改包名/版本号,然后重新
npm publish。 - 注册npm账号时没有邮箱验证。打开www.npmjs.com/login,如果没有邮箱验证,会在页面的最顶端有邮箱未验证的英文提示,点击验证即可。(我在网上看到过有人对这个问题的解决方案是,新注册一个账户,差点笑死)
最后,在npm搜一下自己上传的包,验证是否上传成功(可能会稍有延迟)。