-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* convert function builder to esbuild * fix other function output dir, cleanup negative zero in cleanCoords * add buildClient using esbuild with html plugin, refactor App to receive lazy loaded report clients, fix loose client-ui exports * add esbuild polyfill, address esbuild strict module import - pare down projectClient import paths, switch client away from using top-level gp lib import, shift top-level indexes to prevent pollution of node code in ui code, guard use of process env var * Switch to generating ReportApp.tsx in .build-web with lazy load of report clients * on build copy language assets to .build-web
- Loading branch information
Showing
32 changed files
with
962 additions
and
459 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 1 addition & 5 deletions
6
packages/geoprocessing/scripts/base/datasources/importVectorDatasource.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
packages/geoprocessing/scripts/base/datasources/pathUtils.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import path from "path"; | ||
|
||
export function getJsonPath(dstPath: string, datasourceId: string) { | ||
return path.join(dstPath, datasourceId) + ".json"; | ||
} | ||
|
||
export function getFlatGeobufPath(dstPath: string, datasourceId: string) { | ||
return path.join(dstPath, datasourceId) + ".fgb"; | ||
} | ||
|
||
export function getGeopackagePath(dstPath: string, datasourceId: string) { | ||
return path.join(dstPath, datasourceId) + ".gpkg"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,21 @@ | ||
export PROJECT_PATH=$(pwd) | ||
set -e | ||
echo "" | ||
echo "Building client..." | ||
echo "" | ||
rm -rf .build-web | ||
mkdir .build-web | ||
cp -r src/i18n/lang .build-web | ||
cp -r src/i18n/baseLang .build-web | ||
# Determine correct path. Need to be in @seasketch/geoprocessing root | ||
if test -f "../geoprocessing/scripts/build/build-client.sh"; then | ||
# in monorepo | ||
cd ../geoprocessing | ||
# cd ../geoprocessing | ||
npx tsx ../geoprocessing/scripts/build/buildClient.ts | ||
cp ../geoprocessing/src/assets/favicon.ico $PROJECT_PATH/.build-web/ | ||
else | ||
# production reporting tool | ||
cd node_modules/@seasketch/geoprocessing | ||
# cd node_modules/@seasketch/geoprocessing | ||
npx tsx node_modules/@seasketch/geoprocessing/scripts/build/buildClient.ts | ||
cp node_modules/@seasketch/geoprocessing/src/assets/favicon.ico $PROJECT_PATH/.build-web/ | ||
fi | ||
# Build client | ||
rm -rf .build-web | ||
npx webpack --config scripts/build/webpack.clients.config.js | ||
mv .build-web $PROJECT_PATH/ | ||
cp src/assets/favicon.ico $PROJECT_PATH/.build-web/ | ||
|
||
echo "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import fs from "fs"; | ||
import path from "path"; | ||
import * as esbuild from 'esbuild' | ||
import { generateManifest } from "./generateManifest.js"; | ||
import { GeoprocessingJsonConfig } from "../../src/types/index.js"; | ||
import { PreprocessingBundle, GeoprocessingBundle } from "../types.js"; | ||
import { getHandlerFilenameFromSrcPath } from "../util/handler.js"; | ||
import { Package } from "../../src/types/index.js"; | ||
import { generateHandler } from "./generateHandler.js" | ||
|
||
// Inspect project file contents and generate manifest file | ||
if (!process.env.PROJECT_PATH) throw new Error("Missing PROJECT_PATH"); | ||
|
||
const PROJECT_PATH = process.env.PROJECT_PATH; | ||
const GP_ROOT = path.join(import.meta.dirname, "../../"); | ||
|
||
const srcBuildPath = path.join(GP_ROOT, ".build"); | ||
const destBuildPath = path.join(PROJECT_PATH, ".build"); | ||
|
||
if (!fs.existsSync(srcBuildPath)) { | ||
fs.mkdirSync(srcBuildPath); | ||
} | ||
|
||
const geoprocessing: GeoprocessingJsonConfig = JSON.parse( | ||
fs.readFileSync(path.join(PROJECT_PATH, "geoprocessing.json")).toString() | ||
); | ||
|
||
const packageGp: Package = JSON.parse( | ||
fs.readFileSync("./package.json").toString() | ||
); | ||
|
||
const packageProject: Package = JSON.parse( | ||
fs.readFileSync(path.join(PROJECT_PATH, "package.json")).toString() | ||
); | ||
|
||
|
||
if ( | ||
!geoprocessing.preprocessingFunctions && | ||
!geoprocessing.geoprocessingFunctions | ||
) { | ||
throw new Error("No functions found in geoprocessing.json"); | ||
} | ||
|
||
// For each project function generate root lambda function and bundle into single JS file with all dependencies | ||
const functionPaths = [...geoprocessing.geoprocessingFunctions, ...geoprocessing.preprocessingFunctions] | ||
|
||
console.log('Building geoprocessing functions...\n') | ||
|
||
await Promise.all(functionPaths.map(async funcPath => { | ||
const handlerPath = generateHandler(funcPath, srcBuildPath, PROJECT_PATH) | ||
const bundledPath = handlerPath.replace('Handler', '').replace('.ts', '.js') | ||
console.log(`${bundledPath}`) | ||
const buildResult = await esbuild.build({ | ||
entryPoints: [handlerPath], | ||
bundle: true, | ||
outfile: bundledPath, | ||
platform: 'node', | ||
format: 'esm', | ||
sourcemap: false, | ||
external: ['aws-cdk-lib', 'aws-sdk'] | ||
}) | ||
if (buildResult.errors.length > 0 || buildResult.warnings.length > 0) { | ||
console.log(JSON.stringify(buildResult, null, 2)) | ||
} | ||
})) | ||
|
||
// MANIFEST | ||
|
||
console.log('\nBuilding service manifest...\n') | ||
|
||
/** | ||
* Given full path to source geoprocessing function, requires and returns its pre-generated handler module | ||
*/ | ||
async function getHandlerModule(srcFuncPath: string) { | ||
const name = getHandlerFilenameFromSrcPath(srcFuncPath); | ||
const p = path.join(srcBuildPath, name); | ||
return await import(p); | ||
} | ||
|
||
const preprocessingBundles: PreprocessingBundle[] = | ||
geoprocessing.preprocessingFunctions && | ||
(await Promise.all(geoprocessing.preprocessingFunctions.map(getHandlerModule))); | ||
const geoprocessingBundles: GeoprocessingBundle[] = | ||
geoprocessing.geoprocessingFunctions && | ||
(await Promise.all(geoprocessing.geoprocessingFunctions.map(getHandlerModule))); | ||
|
||
const manifest = generateManifest( | ||
geoprocessing, | ||
packageProject, | ||
preprocessingBundles, | ||
geoprocessingBundles, | ||
packageGp.version | ||
); | ||
const manifestPath = path.join(srcBuildPath, "manifest.json") | ||
console.log(`\nCreating service manifest ${manifestPath}\n`) | ||
fs.writeFileSync( | ||
manifestPath, | ||
JSON.stringify(manifest, null, " ") | ||
); | ||
|
||
|
||
// OTHER_FUNCTIONS | ||
|
||
console.log('Building support lambda functions...\n') | ||
|
||
const otherFunctions = ['src/aws/serviceHandlers.ts', 'src/sockets/sendmessage.ts', 'src/sockets/connect.ts', 'src/sockets/disconnect.ts'] | ||
|
||
await Promise.all(otherFunctions.map(async functionPath => { | ||
const bundledName = path.basename(functionPath).replace('.ts', '.js') | ||
const bundledPath = path.join(destBuildPath, bundledName) | ||
console.log(`${bundledPath}`) | ||
const buildResult = await esbuild.build({ | ||
entryPoints: [functionPath], | ||
bundle: true, | ||
outfile: bundledPath, | ||
platform: 'node', | ||
format: 'esm', | ||
sourcemap: false, | ||
external: ['aws-cdk-lib', 'aws-sdk'] | ||
}) | ||
if (buildResult.errors.length > 0 || buildResult.warnings.length > 0) { | ||
console.log(JSON.stringify(buildResult, null, 2)) | ||
} | ||
})) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import fs from "fs"; | ||
import path from "path"; | ||
import * as esbuild from "esbuild"; | ||
import { GeoprocessingJsonConfig } from "../../src/types/index.js"; | ||
import { Package } from "../../src/types/index.js"; | ||
import { htmlPlugin } from "@craftamap/esbuild-plugin-html"; | ||
import inlineImage from "esbuild-plugin-inline-image"; | ||
import { nodeModulesPolyfillPlugin } from "esbuild-plugins-node-modules-polyfill"; | ||
|
||
if (!process.env.PROJECT_PATH) throw new Error("Missing PROJECT_PATH"); | ||
|
||
const PROJECT_PATH = process.env.PROJECT_PATH; | ||
const GP_ROOT = path.join(import.meta.dirname, "../../"); | ||
const destBuildPath = path.join(PROJECT_PATH, ".build-web"); | ||
|
||
const geoprocessing: GeoprocessingJsonConfig = JSON.parse( | ||
fs.readFileSync(path.join(PROJECT_PATH, "geoprocessing.json")).toString() | ||
); | ||
|
||
const packageGp: Package = JSON.parse( | ||
fs.readFileSync("./package.json").toString() | ||
); | ||
|
||
const packageProject: Package = JSON.parse( | ||
fs.readFileSync(path.join(PROJECT_PATH, "package.json")).toString() | ||
); | ||
|
||
if ( | ||
!geoprocessing.preprocessingFunctions && | ||
!geoprocessing.geoprocessingFunctions | ||
) { | ||
throw new Error("No functions found in geoprocessing.json"); | ||
} | ||
|
||
console.log("Bundling report clients:"); | ||
|
||
const reportClients = geoprocessing.clients.reduce((clientSoFar, curClient) => { | ||
return { [curClient.name]: curClient.source, ...clientSoFar }; | ||
}, {}); | ||
Object.values(reportClients).forEach((clientPath) => console.log(clientPath)); | ||
|
||
// Generate top-level ReportApp.tsx | ||
|
||
const clientImportStr = geoprocessing.clients | ||
.map( | ||
(c) => ` | ||
reportClients["${c.name}"] = React.lazy( | ||
() => import("../${c.source}") | ||
); | ||
` | ||
) | ||
.join(""); | ||
|
||
fs.writeFileSync( | ||
path.join(PROJECT_PATH, ".build-web/ReportApp.tsx"), | ||
` | ||
import React, { Suspense, lazy } from "react"; | ||
import ReactDOM from "react-dom"; | ||
import { App } from "@seasketch/geoprocessing/client-ui"; | ||
const ReportApp = () => { | ||
const reportClients: Record< | ||
string, | ||
React.LazyExoticComponent<() => React.JSX.Element> | ||
> = {}; | ||
${clientImportStr} | ||
return ( | ||
<Suspense fallback={<div>Loading reports...</div>}> | ||
<App reports={reportClients} /> | ||
</Suspense> | ||
); | ||
}; | ||
ReactDOM.render(<ReportApp />, document.body); | ||
` | ||
); | ||
|
||
const buildResult = await esbuild.build({ | ||
entryPoints: [".build-web/ReportApp.tsx"], | ||
bundle: true, | ||
outdir: destBuildPath, | ||
format: "esm", | ||
minify: true, | ||
sourcemap: "linked", | ||
metafile: true, | ||
treeShaking: true, | ||
logLevel: "info", | ||
external: [], | ||
define: { | ||
"process.env.REPORT_CLIENTS": JSON.stringify(reportClients), | ||
"process.env.GP_VERSION": JSON.stringify(packageGp.version), | ||
}, | ||
plugins: [ | ||
//@ts-ignore | ||
inlineImage(), | ||
nodeModulesPolyfillPlugin({ | ||
modules: { | ||
fs: "empty", | ||
}, | ||
}), | ||
htmlPlugin({ | ||
files: [ | ||
{ | ||
entryPoints: [".build-web/ReportApp.tsx"], | ||
filename: "index.html", | ||
scriptLoading: "module", | ||
hash: true, | ||
}, | ||
], | ||
}), | ||
], | ||
}); | ||
if (buildResult.errors.length > 0 || buildResult.warnings.length > 0) { | ||
console.log(JSON.stringify(buildResult, null, 2)); | ||
} |
Oops, something went wrong.