Skip to content

Commit

Permalink
chore: update official configs
Browse files Browse the repository at this point in the history
  • Loading branch information
DiamondMofeng committed Feb 6, 2023
1 parent 3df6441 commit 01d92fd
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 18 deletions.
29 changes: 25 additions & 4 deletions .config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ to issues around working with the project.
Edit the `.eslintrc` file in the project root in order to extend the ESLint configuration.

**Example:**

```json
{
"extends": "./.config/.eslintrc",
"rules": {
"react/prop-types": "off"
"react/prop-types": "off"
}
}
```
Expand All @@ -32,10 +33,11 @@ Edit the `.eslintrc` file in the project root in order to extend the ESLint conf
Edit the `.prettierrc.js` file in the project root in order to extend the Prettier configuration.

**Example:**

```javascript
module.exports = {
// Prettier configuration provided by Grafana scaffolding
...require("./.config/.prettierrc.js"),
...require('./.config/.prettierrc.js'),

semi: false,
};
Expand All @@ -50,7 +52,23 @@ There are two configuration in the project root that belong to Jest: `jest-setup
**`jest-setup.js`:** A file that is run before each test file in the suite is executed. We are using it to
set up the Jest DOM for the testing library and to apply some polyfills. ([link to Jest docs](https://jestjs.io/docs/configuration#setupfilesafterenv-array))

**`jest.config.js`:** The main Jest configuration file that is extending our basic Grafana-tailored setup. ([link to Jest docs](https://jestjs.io/docs/configuration))
**`jest.config.js`:** The main Jest configuration file that extends the Grafana recommended setup. ([link to Jest docs](https://jestjs.io/docs/configuration))

#### ESM errors with Jest

A common issue found with the current jest config involves importing an npm package which only offers an ESM build. These packages cause jest to error with `SyntaxError: Cannot use import statement outside a module`. To work around this we provide a list of known packages to pass to the `[transformIgnorePatterns](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring)` jest configuration property. If need be this can be extended in the following way:

```javascript
process.env.TZ = 'UTC';
const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils');

module.exports = {
// Jest configuration provided by Grafana
...require('./.config/jest.config'),
// Inform jest to only transform specific node_module packages.
transformIgnorePatterns: [nodeModulesToTransform([...grafanaESModules, 'packageName'])],
};
```

---

Expand All @@ -59,6 +77,7 @@ set up the Jest DOM for the testing library and to apply some polyfills. ([link
Edit the `tsconfig.json` file in the project root in order to extend the TypeScript configuration.

**Example:**

```json
{
"extends": "./.config/tsconfig.json",
Expand All @@ -80,6 +99,7 @@ Create a new config file that is going to extend the basic one provided by Grafa
It can live in the project root, e.g. `webpack.config.ts`.

#### 2. Merge the basic config provided by Grafana and your custom setup

We are going to use [`webpack-merge`](https://github.com/survivejs/webpack-merge) for this.

```typescript
Expand All @@ -100,20 +120,21 @@ const config = async (env): Promise<Configuration> => {
};

export default config;

```

#### 3. Update the `package.json` to use the new Webpack config

We need to update the `scripts` in the `package.json` to use the extended Webpack configuration.

**Update for `build`:**

```diff
-"build": "webpack -c ./.config/webpack/webpack.config.ts --env production",
+"build": "webpack -c ./webpack.config.ts --env production",
```

**Update for `dev`:**

```diff
-"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development",
+"dev": "webpack -w -c ./webpack.config.ts --env development",
Expand Down
9 changes: 6 additions & 3 deletions .config/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
*/

const path = require('path');
const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils');

module.exports = {
moduleNameMapper: {
"\\.(css|scss|sass)$": "identity-obj-proxy",
"react-inlinesvg": path.resolve(__dirname, "mocks", "react-inlinesvg.tsx"),
'\\.(css|scss|sass)$': 'identity-obj-proxy',
'react-inlinesvg': path.resolve(__dirname, 'jest', 'mocks', 'react-inlinesvg.tsx'),
},
modulePaths: ['<rootDir>/src'],
setupFilesAfterEnv: ['<rootDir>/jest-setup.js'],
Expand All @@ -35,5 +36,7 @@ module.exports = {
},
],
},
transformIgnorePatterns: [],
// Jest will throw `Cannot use import statement outside module` if it tries to load an
// ES module without it being transformed first. ./config/README.md#esm-errors-with-jest
transformIgnorePatterns: [nodeModulesToTransform(grafanaESModules)],
};
25 changes: 25 additions & 0 deletions .config/jest/mocks/react-inlinesvg.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Due to the grafana/ui Icon component making fetch requests to
// `/public/img/icon/<icon_name>.svg` we need to mock react-inlinesvg to prevent
// the failed fetch requests from displaying errors in console.

import React from 'react';

type Callback = (...args: any[]) => void;

export interface StorageItem {
content: string;
queue: Callback[];
status: string;
}

export const cacheStore: { [key: string]: StorageItem } = Object.create(null);

const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/;

const InlineSVG = ({ src }: { src: string }) => {
// testId will be the file name without extension (e.g. `public/img/icons/angle-double-down.svg` -> `angle-double-down`)
const testId = src.replace(SVG_FILE_NAME_REGEX, '$2');
return <svg xmlns="http://www.w3.org/2000/svg" data-testid={testId} viewBox="0 0 24 24" />;
};

export default InlineSVG;
28 changes: 28 additions & 0 deletions .config/jest/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
*
* In order to extend the configuration follow the steps in .config/README.md
*/

/*
* This utility function is useful in combination with jest `transformIgnorePatterns` config
* to transform specific packages (e.g.ES modules) in a projects node_modules folder.
*/
const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!(${moduleNames.join('|')})\/)`;

// Array of known nested grafana package dependencies that only bundle an ESM version
const grafanaESModules = [
'd3',
'd3-color',
'd3-force',
'd3-interpolate',
'd3-scale-chromatic',
'ol',
'react-colorful',
'uuid',
];

module.exports = {
nodeModulesToTransform,
grafanaESModules
}
23 changes: 12 additions & 11 deletions .config/webpack/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,22 @@ export function hasReadme() {
}

export async function getEntries(): Promise<Record<string, string>> {
const parent = '..';
const pluginsJson = await globAsync('**/src/**/plugin.json');

const plugins = await Promise.all(pluginsJson.map(pluginJson => {
const folder = path.dirname(pluginJson);
return globAsync(`${folder}/module.{ts,tsx,js}`);
}));
const pluginsJson = await globAsync('**/src/**/plugin.json', { absolute: true });

const plugins = await Promise.all(pluginsJson.map((pluginJson) => {
const folder = path.dirname(pluginJson);
return globAsync(`${folder}/module.{ts,tsx,js}`, { absolute: true });
})
);

return plugins.reduce((result, modules) => {
return modules.reduce((result, module) => {
const pluginPath = path.resolve(path.dirname(module), parent);
const pluginPath = path.dirname(module);
const pluginName = path.basename(pluginPath);
const entryName = plugins.length > 1 ? `${pluginName}/module` : 'module';

result[entryName] = path.join(parent, module);
// support bundling nested plugins
const entryName = pluginName === 'src' ? 'module' : `${pluginName}/module`;

result[entryName] = module;
return result;
}, result);
}, {});
Expand Down

0 comments on commit 01d92fd

Please sign in to comment.