如何用TypeScript开发Cytoscape.js扩展?多目录场景的更佳方案
Hey there! Let's break down how to tackle a multi-directory TypeScript setup for your Cytoscape.js extension, and look at better approaches than just relying on raw tsc alone.
First: Basic TypeScript Config for Multi-Directory Projects
If you want to stick with tsc initially, tweaking your tsconfig.json is the key to getting it to handle nested directories smoothly. Let's say your project structure looks like this:
src/ core/ index.ts utils.ts layouts/ custom-layout.ts index.ts
Here's a tsconfig.json that will properly compile all files under src and output them to a clean dist directory:
{ "compilerOptions": { "target": "ES2018", // Balances compatibility and modern features "module": "UMD", // Perfect for Cytoscape extensions (works in browsers, Node, etc.) "declaration": true, // Generates .d.ts type files for TS users "outDir": "./dist", "rootDir": "./src", // Ensures output structure matches your source structure "strict": true, // Enforces type safety "esModuleInterop": true // Fixes common interop issues with CommonJS modules }, "include": ["src/**/*"], // Includes all files/subdirs under src "exclude": ["node_modules", "dist"] // Skip irrelevant directories }
Run tsc and it will compile every .ts file in your nested directories, preserving the folder structure in dist.
Better Approach: Use a Build Tool (Rollup or Webpack)
While tsc works for basic compilation, it doesn't handle things like bundling into UMD format (required for Cytoscape extensions to work everywhere), code minification, or dependency management cleanly. For library development (like a Cytoscape extension), Rollup is my go-to—it's lightweight and optimized for producing clean, small bundles.
Step 1: Install Rollup Dependencies
npm install rollup rollup-plugin-typescript2 @rollup/plugin-node-resolve @rollup/plugin-commonjs --save-dev
Step 2: Configure Rollup
Create a rollup.config.js file at your project root:
import typescript from 'rollup-plugin-typescript2'; import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; export default { input: 'src/index.ts', // Entry point of your extension output: [ { file: 'dist/my-cytoscape-extension.js', format: 'umd', name: 'cytoscapeMyExtension', // Global variable name for browser usage globals: { cytoscape: 'cytoscape' // Tell Rollup not to bundle Cytoscape itself } }, { file: 'dist/my-cytoscape-extension.esm.js', format: 'es' // For modern ES module users } ], external: ['cytoscape'], // Mark Cytoscape as an external dependency plugins: [ resolve(), // Resolves third-party modules from node_modules commonjs(), // Converts CommonJS modules to ES modules typescript({ tsconfig: './tsconfig.json' }) // Uses your existing TS config ] };
Step 3: Add Build Scripts
Update your package.json to include easy-to-run scripts:
{ "scripts": { "build": "rollup -c", "watch": "rollup -c -w" // Auto-rebuild on file changes } }
Now run npm run build and you'll get optimized UMD and ES module bundles in dist—perfect for distributing your Cytoscape extension.
Key TypeScript Tips for Cytoscape Extensions
- Install Cytoscape Types: Grab the official type definitions with
npm install @types/cytoscape --save-devso TypeScript understands Cytoscape's API. - Extend Cytoscape's Type Definitions: To add type hints for your extension's methods, declare extensions to Cytoscape's interfaces:
This gives users of your extension full TypeScript intellisense.import cytoscape from 'cytoscape'; // Extend Cytoscape's core and node interfaces declare module 'cytoscape' { interface Core { myCustomExtension(): void; } interface NodeSingular { myNodeMethod(): void; } } // Register your extension with Cytoscape const registerMyExtension = (cy: typeof cytoscape) => { cy.coreExtensions('myCustomExtension', () => { // Your core extension logic here }); cy.nodeExtensions('myNodeMethod', () => { // Your node-specific logic here }); }; export default registerMyExtension;
Extra Optimizations for Clean Code
- Linting & Formatting: Use ESLint + Prettier to enforce consistent code style across your multi-directory project. Set up rules that match your preferences, and add a pre-commit hook to auto-format code.
- Testing: Use Jest or Mocha with TypeScript support to write tests for your extension—this ensures your nested code works as expected, even as you scale.
- Publish Type Files: In your
package.json, set"types": "dist/index.d.ts"so TypeScript users automatically get type hints when installing your extension.
内容的提问来源于stack exchange,提问作者canbax

