React コンポーネントはパッケージ化されて npm (create-react-app+ts+cesium) にリリースされ、継続的に更新されます~
最新の新しい要件は、コンポーネントを作成して npm で公開することです。このプロジェクトは React18 を使用し、create-react-app スキャフォールディングによって生成された反応フレームワークを使用します。プロジェクトには ts、セシウムなどが含まれます。
以前のプロジェクトは純粋な JS であったため、最初に変換する必要がありました。
反応フレームワークを構築する
スキャフォールディングにより反応フレームワークが生成される
ターミナルにコマンドを入力します。
npx create-react-app my-app --template typescript
設定ファイルを公開する
プロジェクト内には変更が必要な Webpack 構成が多数あるため、構成ファイルは直接公開されます。
ターミナルにコマンドを入力します:
npm run eject
注:改动react框架中内容可能会造成无法eject,可先暴露文件然后再进行其他
エイリアスの構成
config フォルダーで webpack.config.js ファイルを探し、エイリアス (解決オブジェクトの下のエイリアス) を検索します。
コードを次のように変更します。
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
// Allows for better profiling with ReactDevTools
...(isEnvProductionProfile && {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling',
}),
...(modules.webpackAliases || {
}),
// 自定义的别名
'@': path.resolve('src'),
},
このプロジェクトでは ts を使用するため、tsconfig.json ファイルを見つける必要があります。
コードを次のように変更します。
{
"compilerOptions": {
"target": "es5",// 转化成的目标语言
"lib": [
"dom",
"dom.iterable",
"esnext",
"es2015"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"jsx": "react-jsx",
// 别名
"paths": {
"@/*": [
"./src/*"
],
},
},
"include": [
"src",
],
"exclude": ["node_modules", "build",]
}
プロジェクトを実行する
ターミナルにコマンドを入力します。
yarn start
この時点で、プロジェクトは正常に実行されます。
復興プロジェクト
このセクションが必要ない場合は、次のステップに進んでください。このセクションには、プロジェクトの変換中に発生した問題のみが記録されます。
SVGエラー
コンソールのエラー メッセージは次のとおりです。
Uncaught Error: Module build failed (from ./node_modules/@svgr/webpack/dist/index.js):
SyntaxError: unknown file: Namespace tags are not supported by default. React's JSX doesn't support namespace tags. You can set `throwIfNamespace: false` to bypass this warning. (at universalModuleDefinition:15:1)
Module build failed (from ./node_modules/@svgr/webpack/dist/index.js):
SyntaxError: unknown file: Namespace tags are not supported by default. React's JSX doesn't support namespace tags. You can set `throwIfNamespace: false` to bypass this warning.
5 | titleId,
6 | ...props
> 7 | }, ref) => <svg width={
20} height={
20} xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" ref={
ref} aria-labelledby={
titleId} {
...props}>{
title ? <title id={
titleId}>{
title}</title> : null}<path fill="#aaa" d="m3,9l2,0l0,-4l4,0l0,-2l-6,0l0,6l0,0z" /><path fill="#aaa" d="m11,3l0,2l4,0l0,4l2,0l0,-6l-6,0l0,0z" /><path fill="#aaa" d="m15,15l-4,0l0,2l6,0l0,-6l-2,0l0,4l0,0z" /><path fill="#aaa" d="m5,11l-2,0l0,6l6,0l0,-2l-4,0l0,-4l0,0z" /></svg>;
| ^^^^^^^^^
8 | const ForwardRef = forwardRef(SvgFullscreen);
9 | export {
ForwardRef as ReactComponent };
10 | export default __webpack_public_path__ + "static/media/fullscreen.b7fda0177c8659d65ded39b4dd144ca8.svg";
図に示すように:
解決策:
Webpack 設定を変更し、ルート ディレクトリで config フォルダを見つけます。webpack.config を見つけます。 .js ファイル。
webpack.config.js ファイルでモジュール オブジェクトを見つけ、ルール配列を見つけます。
以下に示すようにルールを変更します。
コードは次のとおりです。
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/, /\.svg$/], //添加, /\.svg$/解决打包和报错问题
type: "asset",
parser: {
dataUrlCondition: {
maxSize: imageInlineSizeLimit,
},
},
},
この設定を変更すると、パッケージ化後に他のプロジェクトで参照したときに svg パスが見つからないという問題も解決されます。
セシウム関連の構成
このプロジェクトで使用されているセシウムのバージョンは 1.110.0 です。
プラグインをダウンロードする必要があります:
- セシウム
- コピー-webpack-プラグイン
- ノード-ポリフィル-webpack-プラグイン
バージョンは次のとおりです。
"cesium": "^1.110.0",
"copy-webpack-plugin": "^11.0.0",
"node-polyfill-webpack-plugin": "^2.0.1",
ダウンロードコマンドは以下の通りです。
yarn add cesium -D
yarn add copy-webpack-plugin -D
yarn add node-polyfill-webpack-plugin -D
ルート ディレクトリで config フォルダを見つけます>webpack.config.js ファイルを見つけます
次のコードを webpack.config.js ファイルに追加します。
/* cesium */
const CopyWebpackPlugin = require("copy-webpack-plugin");
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
const cesiumSource = "node_modules/cesium/Source";
const cesiumWorkers = "../Build/Cesium/Workers";
//下面代码需要添加到plugins数组中
new CopyWebpackPlugin({
patterns: [
{
from: path.join(cesiumSource, cesiumWorkers), to: "Workers" },
{
from: path.join(cesiumSource, "Assets"), to: "Assets" },
{
from: path.join(cesiumSource, "Widgets"), to: "Widgets" },
],
}),
new NodePolyfillPlugin(),
new webpack.DefinePlugin({
// env.stringified,
CESIUM_BASE_URL: JSON.stringify(""),
}),
構成は次の図に示すとおりです。
セシウムコードをインスタンス化します。
let viewer = new Cesium.Viewer(mapContainer, {
animation: false, //是否创建动画小器件,左下角仪表
baseLayerPicker: false, //是否显示图层选择器
fullscreenButton: false, //是否显示全屏按钮
geocoder: false, //是否显示geocoder小器件,右上角查询按钮
homeButton: false, //是否显示Home按钮
infoBox: false, //是否显示信息框
sceneModePicker: false, //是否显示3D/2D选择器,与scene3DOnly不能同时为true
selectionIndicator: false, //是否显示选取指示器组件
timeline: false, //是否显示时间轴
navigationHelpButton: false, //是否显示右上角的帮助按钮
scene3DOnly: false, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
// terrainProvider: Cesium.createWorldTerrain(),
orderIndependentTranslucency: false,
contextOptions: {
//cesium状态下允许canvas转图片convertToImage
webgl: {
alpha: true,
depth: false,
stencil: true,
antialias: true,
premultipliedAlpha: true,
preserveDrawingBuffer: true,
failIfMajorPerformanceCaveat: true,
},
allowTextureFilterAnisotropic: true,
},
// baseLayer: ,
});
viewer.imageryLayers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({
url: "地址xxxxxxxxxx",
maximumLevel: 18,
})
);
viewer.scene.sun.show = false;
viewer.scene.moon.show = false;
viewer.scene.skyBox.show = true;
viewer.scene.backgroundColor = new Cesium.Color(0.0, 0.0, 0.0, 0.0);
コードミラー構成
バージョンは次のとおりです。
"@codemirror/lang-javascript": "^6.2.1",
"@types/codemirror": "^5.60.12",
"codemirror": "5.38.0",
バージョンが異なればインスタンス化方法も異なるため、スタイル テーマを有効にするには導入する必要があります。
コードは次のとおりです。
import CodeMirror from "codemirror";
import {
javascript } from "@codemirror/lang-javascript";
import "codemirror/lib/codemirror.css";
import "codemirror/theme/monokai.css"; //主题样式文件
import "codemirror/mode/javascript/javascript"; //javascript模式
import "codemirror/addon/hint/show-hint.css";
import "codemirror/addon/hint/show-hint";
// var codemirror = new EditorView({
// extensions: [basicSetup, javascript()],
// parent: container.dom!,
// });
var codemirror = CodeMirror(container.dom, {
value: "",
lineNumbers: true,
lineWrapping: true,
matchBrackets: true,
indentWithTabs: true,
tabSize: 4,
indentUnit: 4,
mode: "javascript",
});
codemirror.setOption("theme", "monokai");
codemirror.on("change", function () {
if (codemirror.state.focused === false) return;
clearTimeout(delay);
delay = setTimeout(function () {
if (errorLine) {
codemirror.removeLineClass(errorLine, "CodeMirror-errorLine");
errorLine = null;
}
if (currentScript !== null) {
currentScript.source = codemirror.getValue();
editor.signals.scriptChanged.dispatch();
} else if (currentEffect !== null) {
var error;
var currentSource = currentEffect.source;
editor.timeline.reset();
try {
currentEffect.source = codemirror.getValue();
editor.compileEffect(currentEffect);
} catch (e) {
error = e.name + " : " + e.message; // e.stack, e.columnNumber, e.lineNumber
if (/Chrome/i.test(navigator.userAgent)) {
var result = /<anonymous>:([0-9]+):([0-9+])/g.exec(e.stack);
if (result !== null) errorLine = parseInt(result[1]) - 3;
} else if (/Firefox/i.test(navigator.userAgent)) {
var result = /Function:([0-9]+):([0-9+])/g.exec(e.stack);
if (result !== null) errorLine = parseInt(result[1]) - 1;
}
if (errorLine !== null) {
codemirror.addLineClass(
errorLine,
"errorLine",
"CodeMirror-errorLine"
);
}
}
editor.timeline.update(editor.player.currentTime);
if (error !== undefined) {
errorDiv.setDisplay("");
errorText.setValue("⌦ " + error);
currentEffect.source = currentSource;
} else {
errorDiv.setDisplay("none");
}
}
}, 1000);
});
React での src ファイルの外部のコンテンツの参照
create-react-app スキャフォールディングによって生成されたフレームワークは src ディレクトリの外部からの参照を禁止しているため、webpack 構成を変更する必要があります。
webpack.config.js ファイルの変更コードは次のとおりです。
解決オブジェクト プラグイン配列を見つけます
plugins: [
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appRoot, [
paths.appPackageJson,
reactRefreshRuntimeEntry,
reactRefreshWebpackPluginRuntimeEntry,
babelRuntimeEntry,
babelRuntimeEntryHelpers,
babelRuntimeRegenerator,
]),
],
config で paths.js ファイルを見つけます。
上記でインポートしたパスを paths.js ファイルに入力します。
コードは次のとおりです。< /span>
module.exports = {
dotenv: resolveApp('.env'),
appPath: resolveApp('.'),
appBuild: resolveApp(buildPath),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
buildEntry: resolveModule(resolveApp, 'src/gis'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appTsConfig: resolveApp('tsconfig.json'),
appJsConfig: resolveApp('jsconfig.json'),
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveModule(resolveApp, 'src/setupTests'),
proxySetup: resolveApp('src/setupProxy.js'),
appNodeModules: resolveApp('node_modules'),
appWebpackCache: resolveApp('node_modules/.cache'),
appTsBuildInfoFile: resolveApp('node_modules/.cache/tsconfig.tsbuildinfo'),
swSrc: resolveModule(resolveApp, 'src/service-worker'),
publicUrlOrPath,
appRoot: resolveApp(''),
};
パック
パッケージの入口と出口の構成
プロジェクトの最終エクスポートが js に変更されるため、パッケージ化された js ファイルの名前とパスが変更されます。
webpack.config.js ファイルで、出力オブジェクトを見つけます。
コードを次のように変更します。
output: {
// The build folder.
path: paths.appBuild,
// Add /* filename */ comments to generated require()s in the output.
pathinfo: isEnvDevelopment,
// There will be one main bundle, and one file per asynchronous chunk.
// In development, it does not produce real files.
// filename: isEnvProduction
// ? 'static/js/[name].[contenthash:8].js'
// : isEnvDevelopment && 'static/js/bundle.js',
filename: "index.js",//出口js文件路径及其名称
library: {
name: "library", //库输出变量名
type: "umd", //库类型
export: "Gis", //导出变量名
auxiliaryComment: "test component",
},
// There are also additional JS chunk files if you use code splitting.
chunkFilename: isEnvProduction
? "static/js/[name].[contenthash:8].chunk.js"
: isEnvDevelopment && "static/js/[name].chunk.js",
assetModuleFilename: "static/media/[name].[hash][ext]",
// webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: paths.publicUrlOrPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: isEnvProduction
? (info) =>
path
.relative(paths.appSrc, info.absoluteResourcePath)
.replace(/\\/g, "/")
: isEnvDevelopment &&
((info) =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, "/")),
},
プロジェクト構造に従ってts宣言ファイルをパッケージ化して出力する
create-react-app スキャフォールドで生成された Webpack は、ts-loader の代わりに babel-loader を使用して ts をコンパイルするため、ts-loader の依存関係を追加する必要があります。
ts-loader のバージョンは次のとおりです。
"ts-loader": "^9.5.0"
webpack.config.js を変更します。
//改代码为修改之前的代码
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),
presets: [
[
require.resolve('babel-preset-react-app'),
{
runtime: hasJsxRuntime ? 'automatic' : 'classic',
},
],
],
plugins: [
isEnvDevelopment &&
shouldUseReactRefresh &&
require.resolve('react-refresh/babel'),
].filter(Boolean),
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
// See #6846 for context on why cacheCompression is disabled
cacheCompression: false,
compact: isEnvProduction,
},
},
//修改之后的代码如下
{
test: /\.(ts|tsx)$/,
loader: require.resolve("ts-loader"),
options: {
transpileOnly: false,
},
},
{
test: /\.(js|mjs|jsx)$/,
include: paths.appSrc,
loader: require.resolve("babel-loader"),
options: {
customize: require.resolve(
"babel-preset-react-app/webpack-overrides"
),
presets: [
[
require.resolve("babel-preset-react-app"),
{
runtime: hasJsxRuntime ? "automatic" : "classic",
},
],
],
plugins: [
isEnvDevelopment &&
shouldUseReactRefresh &&
require.resolve("react-refresh/babel"),
].filter(Boolean),
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
// See #6846 for context on why cacheCompression is disabled
cacheCompression: false,
compact: isEnvProduction,
},
},
実際、このアイデアは、コンパイルされた ts ルールを他のルールとは別に記述し、ts には ts-loader を使用するというものです。
テスト用に別のプロジェクトをパッケージ化して導入する
パッケージ化されたエクスポートは src ディレクトリ内のインデックスであるため、このコンポーネントをエクスポートする必要があります。そのため、index.tsx の名前を変更し、エクスポートされたコンポーネントへの参照を追加します。
追加Index.ts ファイル:
import Gis from "./views/gis/Gis";
export {
Gis };
パッケージ化コマンドを実行します。
yarn build
余談ですが、run を追加しなくても start と build を実行できます。
パッケージ化されたファイルを別の空のプロジェクトにコピーし、空のプロジェクトにプラグインを導入します。
コードは次のとおりです。
import React from 'react';
import './App.css';
import Gis from "../build/index.js"
function App() {
return (
<div className="App">
<Gis />
</div>
);
}
export default App;
現時点では操作は成功しています。
続く~~
エラーレポートがある場合は、該当するエラーレポートに従って問題を解決してください。
npmリリースプロセス
ログインnpm
ターミナルにコマンドを入力します。
npm login
ユーザー名、パスワード、メール アドレスを順番に入力します。
メール アドレスの確認コードも入力する場合もあります。
次のようなエラーが報告される場合もあります。以下に示す:
エラーメッセージは次のとおりです。
code F403
npm ERR!
npm ERR!403 403 Forbidden - PU https://registry.npmirror. con/-/user/org. couchdb.user:csiyu - [FORBIDDEN] Public registration is not allowetnpm ERR!403 In most cases, you or one of your dependencies are requestingnpmERr!403 a package version that is forbidden by your security policy, ornpm ERR! 403 on a server you do not have access to.
npmERR! A complete log of this run can be found in:npmERR!/Users/chensiyu/.npm/_ logs/2023-10 27T07 10 40 630Z-debug -0.log![请添加图片描述](https://img-blog.csdnimg.cn/b540f3eca1d3407ba8dc1734f3bddd69.jpeg)
エラーの理由は npm ミラー ソースにあります。ミラー ソースを切り替えてください。
ターミナルにコマンドを入力してください:
npm config set registry https://registry.npmjs.org/
もう一度ログインしてください。
リリース
ターミナルにコマンドを入力します。
npm publish
次のエラーが発生した場合:
npm ERR! code E403
npm ERR! 403 403 Forbidden - PUT https://registry.npmjs.org/test-xxx - You do not have permission to publish “test-xxx”. Are you logged in as the correct user?
npm ERR! 403 In most cases, you or one of your dependencies are requesting
npm ERR! 403 a package version that is forbidden by your security policy, or
npm ERR! 403 on a server you do not have access to.
パッケージ名がnpmと競合しているためです。パッケージ名を変更して再公開してください。
成功したリリースは次のようになります。