Skip to content

Commit

Permalink
Add SystemJS plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
timkendrick committed Jan 8, 2024
1 parent 4d87ed4 commit 45dbef6
Show file tree
Hide file tree
Showing 16 changed files with 1,147 additions and 158 deletions.
1 change: 1 addition & 0 deletions packages/systemjs-plugin/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/dist/
33 changes: 33 additions & 0 deletions packages/systemjs-plugin/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module.exports = {
root: true,
env: {
es2022: true,
},
extends: ['plugin:prettier/recommended'],
plugins: ['@typescript-eslint'],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
overrides: [
{
files: ['.eslintrc.cjs'],
env: {
node: true,
},
parserOptions: {
sourceType: 'script',
},
},
],
rules: {
'no-warning-comments': [
'warn',
{
terms: ['fixme'],
},
],
'prettier/prettier': 'warn',
},
};
1 change: 1 addition & 0 deletions packages/systemjs-plugin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/dist/
55 changes: 55 additions & 0 deletions packages/systemjs-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# @ag-grid-community/systemjs-plugin

> _SystemJS plugin for TypeScript/JSX/CSS source files_
## Usage

Embed the script in your HTML entry point, after the SystemJS `s.js` or `system.js` script:

```
<script src="path/to/systemjs/dist/system.js" />
<script src="path/to/ag-grid-systemjs-plugin/dist/index.js"/>
```

This will enforce the following behavior when loading SystemJS modules:

- All TypeScript/JSX source files will be transformed via the Babel plugins specified in the [bundled Babel configuration](./src/babel/plugins.ts)

- All CSS source files loaded by SystemJS will have their contents automatically injected into the HTML document head

Note that this CSS loading behavior diverges from the standard SystemJS CSS Modules behavior implemented by the `module-types` extra (bundled in `system.js`), which loads the CSS file as a module for use in a JavaScript module. For this reason, this plugin disables the underlying `module-types` extra, which will have the side-effect that any JSON or WASM modules that would usually be handled by the `module-types` loader must now be handled separately.

### Custom configuration

By default, the plugin will run the Babel transform on all loaded SystemJS URLs except from JS/CSS/JSON/WASM resources.

This can be undesirable when e.g. depending on a published UMD library, which can be loaded directly via the SystemJS AMD transform without requiring further processing.

To determine which URLs are transformed, declare a global `systemjs.babel.shouldTransform` function before the plugin is loaded.

For example, the following configuration will only transform local non-JSON resources:

```
<script>
var systemjs = {
babel: {
shouldTransform(url, extension, contentType) {
if (new URL(url).hostname !== 'localhost') return true;
const contentTypes = contentType ? contentType.split(';') : [];
if (contentTypes.includes('application/json')) return false;
if (extension && extension === '.json') return false;
return true;
}
}
};
</script>
<script src="path/to/systemjs/dist/s.js" />
<script src="path/to/ag-grid-systemjs-plugin/dist/index.js"/>
```

### Developing

This package following npm scripts:

- `build`: Lint and build the package (outputs the compiled package into the `./dist` directory)
- `lint`: Lint the source code
7 changes: 7 additions & 0 deletions packages/systemjs-plugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import babelLoader from './src/plugins/babel-loader';
import injectCssLoader from './src/plugins/inject-css-loader';
import { registerSystemJsPlugin } from './src/utils/systemjs';

// Register the SystemJS plugins
registerSystemJsPlugin(injectCssLoader);
registerSystemJsPlugin(babelLoader);
50 changes: 50 additions & 0 deletions packages/systemjs-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"private": true,
"name": "@ag-grid-community/systemjs-plugin",
"version": "0.1.0",
"description": "SystemJS plugin for TypeScript/JSX/CSS source files",
"license": "MIT",
"author": "AG Grid <[email protected]>",
"homepage": "https://www.ag-grid.com/",
"repository": {
"type": "git",
"url": "https://github.com/ag-grid/devtools.git"
},
"bugs": {
"url": "https://github.com/ag-grid/devtools/issues"
},
"type": "module",
"main": "index.ts",
"scripts": {
"build": "pnpm run build:lib && pnpm run build:pkg",
"build:lib": "vite build",
"build:pkg": "pnpm run --filter build-tools pkg $PWD $PWD/dist/package.json",
"lint": "pnpm run '/^lint:.*/'",
"lint:eslint": "eslint --ext js,cjs,mjs,ts .",
"lint:typescript": "tsc --noEmit"
},
"pkg": {
"main": "./index.js"
},
"devDependencies": {
"@ag-grid-devtools/build-config": "workspace:*",
"@babel/core": "^7.23.7",
"@babel/plugin-proposal-dynamic-import": "^7.18.6",
"@babel/plugin-proposal-export-default-from": "^7.23.3",
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
"@babel/plugin-proposal-numeric-separator": "^7.18.6",
"@babel/plugin-syntax-class-properties": "^7.12.13",
"@babel/plugin-transform-modules-systemjs": "^7.23.3",
"@babel/plugin-transform-react-jsx": "^7.23.4",
"@babel/plugin-transform-typescript": "^7.23.6",
"@types/babel__core": "^7.20.5",
"@typescript-eslint/eslint-plugin": "6.17.0",
"@typescript-eslint/parser": "6.17.0"
},
"peerDependencies": {
"eslint": "^8",
"typescript": "^5",
"vite": "^4",
"vite-plugin-node-polyfills": "^0.19"
}
}
1 change: 1 addition & 0 deletions packages/systemjs-plugin/prettier.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@ag-grid-devtools/build-config/templates/prettier/prettier.config.mjs';
87 changes: 87 additions & 0 deletions packages/systemjs-plugin/src/babel/plugins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import type * as babel from '@babel/core';
import babelPluginNumericSeparator from '@babel/plugin-proposal-numeric-separator';
import babelPluginProposalDynamicImport from '@babel/plugin-proposal-dynamic-import';
import babelPluginProposalExportDefaultFrom from '@babel/plugin-proposal-export-default-from';
import babelPluginProposalExportNamespaceFrom from '@babel/plugin-proposal-export-namespace-from';
import babelPluginSyntaxClassProperties from '@babel/plugin-syntax-class-properties';
import babelPluginTransformModulesSystemJS from '@babel/plugin-transform-modules-systemjs';
import babelPluginTransformReactJsx from '@babel/plugin-transform-react-jsx';
import babelPluginTransformTypescript from '@babel/plugin-transform-typescript';
import './types.d.ts';

const SYNTAX_PLUGINS: babel.ParserOptions['plugins'] = [
'asyncGenerators',
'classProperties',
'classPrivateProperties',
'classPrivateMethods',
'dynamicImport',
'importMeta',
'nullishCoalescingOperator',
'numericSeparator',
'optionalCatchBinding',
'optionalChaining',
'objectRestSpread',
'topLevelAwait',
];

const DEFAULT_PLUGINS = [
babelPluginTransformModulesSystemJS,
babelPluginProposalDynamicImport,
babelPluginProposalExportDefaultFrom,
babelPluginProposalExportNamespaceFrom,
babelPluginSyntaxClassProperties,
babelPluginNumericSeparator,
];

const TS_PLUGINS: Array<babel.PluginItem> = [
[
babelPluginTransformTypescript,
{
onlyRemoveTypeImports: true,
},
],
...DEFAULT_PLUGINS,
];

const TSX_PLUGINS: Array<babel.PluginItem> = [
[
babelPluginTransformTypescript,
{
isTSX: true,
onlyRemoveTypeImports: true,
},
],
[
babelPluginTransformReactJsx,
{
runtime: 'automatic',
},
],
...DEFAULT_PLUGINS,
];

const JSX_PLUGINS: Array<babel.PluginItem> = [
[
babelPluginTransformReactJsx,
{
runtime: 'automatic',
},
],
...DEFAULT_PLUGINS,
];

const PLUGINS_BY_EXTENSION: Record<string, Array<babel.PluginItem>> = {
'.ts': TS_PLUGINS,
'.tsx': TSX_PLUGINS,
'.jsx': JSX_PLUGINS,
};

export function getBabelPlugins(extension: string | null): {
syntax: babel.ParserOptions['plugins'];
transform: Array<babel.PluginItem>;
} {
return {
syntax: SYNTAX_PLUGINS,
transform: (extension && PLUGINS_BY_EXTENSION[extension]) || DEFAULT_PLUGINS,
};
}
47 changes: 47 additions & 0 deletions packages/systemjs-plugin/src/babel/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
declare module '@babel/plugin-proposal-numeric-separator' {
import type * as Babel from '@babel/core';
import type { PluginObj } from '@babel/core';
export default function (babel: typeof Babel): PluginObj;
}

declare module '@babel/plugin-proposal-dynamic-import' {
import type * as Babel from '@babel/core';
import type { PluginObj } from '@babel/core';
export default function (babel: typeof Babel): PluginObj;
}

declare module '@babel/plugin-proposal-export-default-from' {
import type * as Babel from '@babel/core';
import type { PluginObj } from '@babel/core';
export default function (babel: typeof Babel): PluginObj;
}

declare module '@babel/plugin-proposal-export-namespace-from' {
import type * as Babel from '@babel/core';
import type { PluginObj } from '@babel/core';
export default function (babel: typeof Babel): PluginObj;
}

declare module '@babel/plugin-syntax-class-properties' {
import type * as Babel from '@babel/core';
import type { PluginObj } from '@babel/core';
export default function (babel: typeof Babel): PluginObj;
}

declare module '@babel/plugin-transform-modules-systemjs' {
import type * as Babel from '@babel/core';
import type { PluginObj } from '@babel/core';
export default function (babel: typeof Babel): PluginObj;
}

declare module '@babel/plugin-transform-react-jsx' {
import type * as Babel from '@babel/core';
import type { PluginObj } from '@babel/core';
export default function (babel: typeof Babel): PluginObj;
}

declare module '@babel/plugin-transform-typescript' {
import type * as Babel from '@babel/core';
import type { PluginObj } from '@babel/core';
export default function (babel: typeof Babel): PluginObj;
}
Loading

0 comments on commit 45dbef6

Please sign in to comment.