diff --git a/change/@fluentui-eslint-plugin-react-components-3091f3d8-8015-47e4-b973-bcdbbcb4e852.json b/change/@fluentui-eslint-plugin-react-components-3091f3d8-8015-47e4-b973-bcdbbcb4e852.json new file mode 100644 index 00000000000000..199e5bdf47393e --- /dev/null +++ b/change/@fluentui-eslint-plugin-react-components-3091f3d8-8015-47e4-b973-bcdbbcb4e852.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: support ESM plugin imports", + "packageName": "@fluentui/eslint-plugin-react-components", + "email": "kirtiar15502@gmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/eslint-plugin-react-components/.swcrc b/packages/react-components/eslint-plugin-react-components/.swcrc index b4ffa86dee3067..38899f8a15e391 100644 --- a/packages/react-components/eslint-plugin-react-components/.swcrc +++ b/packages/react-components/eslint-plugin-react-components/.swcrc @@ -16,6 +16,7 @@ "decorators": false, "dynamicImport": false }, + "baseUrl": ".", "externalHelpers": true, "transform": { "react": { diff --git a/packages/react-components/eslint-plugin-react-components/etc/eslint-plugin-react-components.api.md b/packages/react-components/eslint-plugin-react-components/etc/eslint-plugin-react-components.api.md index bc570c9853879c..fc126bf17d3038 100644 --- a/packages/react-components/eslint-plugin-react-components/etc/eslint-plugin-react-components.api.md +++ b/packages/react-components/eslint-plugin-react-components/etc/eslint-plugin-react-components.api.md @@ -28,6 +28,31 @@ export const meta: { version: string; }; +// @public (undocumented) +const plugin: { + meta: { + name: string; + version: string; + }; + configs: { + recommended: { + plugins: string[]; + rules: {}; + }; + 'flat/recommended': { + plugins: { + [x: string]: ESLint.Plugin; + }; + rules: {}; + }; + }; + rules: { + "enforce-use-client": RuleModule<"missingUseClient" | "unnecessaryUseClient", [(RuleOptions | undefined)?], unknown, RuleListener>; + "prefer-fluentui-v9": RuleModule<"replaceFluent8With9" | "replaceIconWithJsx" | "replaceStackWithFlex" | "replaceFocusZoneWithTabster", {}[], unknown, RuleListener>; + }; +}; +export default plugin; + // @public (undocumented) export const rules: { "enforce-use-client": RuleModule<"missingUseClient" | "unnecessaryUseClient", [(RuleOptions | undefined)?], unknown, RuleListener>; diff --git a/packages/react-components/eslint-plugin-react-components/src/index.ts b/packages/react-components/eslint-plugin-react-components/src/index.ts index b3884c69a70d65..7ce918173a0dd9 100644 --- a/packages/react-components/eslint-plugin-react-components/src/index.ts +++ b/packages/react-components/eslint-plugin-react-components/src/index.ts @@ -1,9 +1,11 @@ import type { ESLint } from 'eslint'; -import { name, version } from '../package.json'; +import packageJson from '../package.json'; import { RULE_NAME as enforceUseClientName, rule as enforceUseClient } from './rules/enforce-use-client'; import { RULE_NAME as preferFluentUIV9Name, rule as preferFluentUIV9 } from './rules/prefer-fluentui-v9'; +const { name, version } = packageJson; + export const meta = { name, version, @@ -35,10 +37,13 @@ const plugin = { configs, rules, }; +export default plugin; // Flat config for eslint v9 configs['flat/recommended'].plugins = { [name]: plugin as unknown as ESLint.Plugin, }; -module.exports = plugin; +if (typeof module !== 'undefined') { + module.exports = plugin; +} diff --git a/packages/react-components/eslint-plugin-react-components/tsconfig.lib.json b/packages/react-components/eslint-plugin-react-components/tsconfig.lib.json index 3bf0a059bc2c14..58459b79c2298c 100644 --- a/packages/react-components/eslint-plugin-react-components/tsconfig.lib.json +++ b/packages/react-components/eslint-plugin-react-components/tsconfig.lib.json @@ -8,7 +8,8 @@ "outDir": "../../../dist/out-tsc", "inlineSources": true, "types": ["environment", "node"], - "module": "CommonJS" + "module": "CommonJS", + "allowSyntheticDefaultImports": true }, "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx"], "include": ["./src/**/*.ts", "./src/**/*.tsx"] diff --git a/tools/workspace-plugin/src/executors/build/__fixtures__/executor/libs/proj/src/package-info.json b/tools/workspace-plugin/src/executors/build/__fixtures__/executor/libs/proj/src/package-info.json new file mode 100644 index 00000000000000..77820f1e6c312f --- /dev/null +++ b/tools/workspace-plugin/src/executors/build/__fixtures__/executor/libs/proj/src/package-info.json @@ -0,0 +1,3 @@ +{ + "name": "proj" +} diff --git a/tools/workspace-plugin/src/executors/build/__fixtures__/executor/libs/proj/src/package-info.ts b/tools/workspace-plugin/src/executors/build/__fixtures__/executor/libs/proj/src/package-info.ts new file mode 100644 index 00000000000000..fd944eefaa0bf1 --- /dev/null +++ b/tools/workspace-plugin/src/executors/build/__fixtures__/executor/libs/proj/src/package-info.ts @@ -0,0 +1,3 @@ +import packageJson from './package-info.json'; + +export const packageName = packageJson.name; diff --git a/tools/workspace-plugin/src/executors/build/__fixtures__/executor/libs/proj/tsconfig.lib.json b/tools/workspace-plugin/src/executors/build/__fixtures__/executor/libs/proj/tsconfig.lib.json index 7b3b02933dd526..705b464ef3546a 100644 --- a/tools/workspace-plugin/src/executors/build/__fixtures__/executor/libs/proj/tsconfig.lib.json +++ b/tools/workspace-plugin/src/executors/build/__fixtures__/executor/libs/proj/tsconfig.lib.json @@ -3,7 +3,9 @@ "compilerOptions": { "outDir": "./dist/out-tsc", "declaration": true, - "types": [] + "types": [], + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true }, "include": ["src/*.ts"], "exclude": ["src/*.spec.ts"] diff --git a/tools/workspace-plugin/src/executors/build/executor.spec.ts b/tools/workspace-plugin/src/executors/build/executor.spec.ts index e43d815289d8aa..2327b682fa158f 100644 --- a/tools/workspace-plugin/src/executors/build/executor.spec.ts +++ b/tools/workspace-plugin/src/executors/build/executor.spec.ts @@ -103,9 +103,9 @@ describe('Build Executor', () => { expect(stripIndents`${clearLogs}`).toEqual(stripIndents` Cleaning outputs: - - ${workspaceRoot}/libs/proj/lib-commonjs - - ${workspaceRoot}/libs/proj/lib - - ${workspaceRoot}/libs/proj/dist/assets/spec.md + - ${join(workspaceRoot, 'libs/proj/lib-commonjs')} + - ${join(workspaceRoot, 'libs/proj/lib')} + - ${join(workspaceRoot, 'libs/proj/dist/assets/spec.md')} `); expect(restOfLogs).toEqual([ @@ -116,22 +116,22 @@ describe('Build Executor', () => { expect(loggerVerboseSpy.mock.calls.flat()).toEqual([ `Applying transforms: 0`, - `babel: transformed ${workspaceRoot}/libs/proj/lib/greeter.styles.js`, + `babel: transformed ${join(workspaceRoot, 'libs/proj/lib/greeter.styles.js')}`, `Applying transforms: 0`, ]); expect(rmMock.mock.calls.flat()).toEqual([ - `${workspaceRoot}/libs/proj/lib-commonjs`, + join(workspaceRoot, 'libs/proj/lib-commonjs'), { force: true, recursive: true, }, - `${workspaceRoot}/libs/proj/lib`, + join(workspaceRoot, 'libs/proj/lib'), { force: true, recursive: true, }, - `${workspaceRoot}/libs/proj/dist/assets/spec.md`, + join(workspaceRoot, 'libs/proj/dist/assets/spec.md'), { force: true, recursive: true, @@ -154,6 +154,8 @@ describe('Build Executor', () => { 'greeter.styles.js.map', 'index.js', 'index.js.map', + 'package-info.js', + 'package-info.js.map', ]); expect(readdirSync(join(workspaceRoot, 'libs/proj/lib-commonjs'))).toEqual([ 'greeter.js', @@ -162,6 +164,8 @@ describe('Build Executor', () => { 'greeter.styles.js.map', 'index.js', 'index.js.map', + 'package-info.js', + 'package-info.js.map', ]); // ==================================== @@ -231,6 +235,12 @@ describe('Build Executor', () => { } " `); + expect(readFileSync(join(workspaceRoot, 'libs/proj/lib/package-info.js'), 'utf-8')).toContain( + `from './package-info.json' with { type: 'json' };`, + ); + expect(readFileSync(join(workspaceRoot, 'libs/proj/lib-commonjs/package-info.js'), 'utf-8')).toContain( + `require("./package-info.json")`, + ); // ===================== // assert griffel AOT diff --git a/tools/workspace-plugin/src/executors/build/lib/swc.ts b/tools/workspace-plugin/src/executors/build/lib/swc.ts index 370868830a8b4b..8a459429a20614 100644 --- a/tools/workspace-plugin/src/executors/build/lib/swc.ts +++ b/tools/workspace-plugin/src/executors/build/lib/swc.ts @@ -54,10 +54,14 @@ export async function compileSwc( }); // Strip @jsx comments, see https://github.com/microsoft/fluentui/issues/29126 - const resultCode = result.code + let resultCode = result.code .replace('/** @jsxRuntime automatic */', '') .replace('/** @jsxImportSource @fluentui/react-jsx-runtime */', ''); + if (module === 'es6') { + resultCode = addJsonImportAttributes(resultCode); + } + const jsFileName = fileName.replace(tsFileExtensionRegex, '.js'); const compiledFilePath = join(absoluteOutputPath, jsFileName); @@ -85,3 +89,7 @@ async function applyTransforms(filePath: string, transforms?: Array): await transform(filePath); } } + +function addJsonImportAttributes(code: string): string { + return code.replace(/from\s+(['"][^'"]+\.json['"])\s*;/g, "from $1 with { type: 'json' };"); +}