From c54d2133a7dd74c347c5e1cc8d8fe853475c6cd8 Mon Sep 17 00:00:00 2001 From: Esteban Beltran Date: Wed, 26 Apr 2023 11:45:34 +0200 Subject: [PATCH] Build: Setup webpack configuration for direct-input bundled datasource (#67199) --- .../internal/input-datasource/.gitignore | 1 + .../__mocks__/d3-interpolate.ts | 1 + .../internal/input-datasource/jest.config.js | 26 +++- .../internal/input-datasource/package.json | 25 +-- .../internal/input-datasource/tsconfig.json | 8 + .../input-datasource/webpack.config.ts | 146 ++++++++++++++++++ yarn.lock | 34 ++-- 7 files changed, 198 insertions(+), 43 deletions(-) create mode 100644 plugins-bundled/internal/input-datasource/.gitignore create mode 100644 plugins-bundled/internal/input-datasource/__mocks__/d3-interpolate.ts create mode 100644 plugins-bundled/internal/input-datasource/webpack.config.ts diff --git a/plugins-bundled/internal/input-datasource/.gitignore b/plugins-bundled/internal/input-datasource/.gitignore new file mode 100644 index 00000000000..61c3bc75a05 --- /dev/null +++ b/plugins-bundled/internal/input-datasource/.gitignore @@ -0,0 +1 @@ +.yarn diff --git a/plugins-bundled/internal/input-datasource/__mocks__/d3-interpolate.ts b/plugins-bundled/internal/input-datasource/__mocks__/d3-interpolate.ts new file mode 100644 index 00000000000..f053ebf7976 --- /dev/null +++ b/plugins-bundled/internal/input-datasource/__mocks__/d3-interpolate.ts @@ -0,0 +1 @@ +module.exports = {}; diff --git a/plugins-bundled/internal/input-datasource/jest.config.js b/plugins-bundled/internal/input-datasource/jest.config.js index bcf17c9087d..88c2dfafc09 100644 --- a/plugins-bundled/internal/input-datasource/jest.config.js +++ b/plugins-bundled/internal/input-datasource/jest.config.js @@ -1,8 +1,18 @@ -// This file is needed because it is used by vscode and other tools that -// call `jest` directly. However, unless you are doing anything special -// do not edit this file - -const standard = require('@grafana/toolkit/src/config/jest.plugin.config'); - -// This process will use the same config that `yarn test` is using -module.exports = standard.jestConfig(); +module.exports = { + testEnvironment: 'jest-environment-jsdom', + preset: 'ts-jest', + extensionsToTreatAsEsm: ['.ts'], + transform: { + '^.+\\.(t|j)sx?$': [ + 'ts-jest', + { + useESM: true, + isolatedModules: true, + allowJs: true, + }, + ], + }, + moduleNameMapper: { + '^d3-interpolate$': '/__mocks__/d3-interpolate.ts', + }, +}; diff --git a/plugins-bundled/internal/input-datasource/package.json b/plugins-bundled/internal/input-datasource/package.json index aa6567a463a..fd04cac7c97 100644 --- a/plugins-bundled/internal/input-datasource/package.json +++ b/plugins-bundled/internal/input-datasource/package.json @@ -8,27 +8,28 @@ "url": "http://github.com/grafana/grafana.git" }, "scripts": { - "build": "grafana-toolkit plugin:build", - "test": "grafana-toolkit plugin:test", - "dev": "grafana-toolkit plugin:dev", - "watch": "grafana-toolkit plugin:dev --watch" + "build": "yarn test && webpack -c webpack.config.ts --env production", + "dev": "webpack -w -c webpack.config.ts --env development", + "test": "jest -c jest.config.js" }, "author": "Grafana Labs", "devDependencies": { - "@grafana/toolkit": "10.0.0-pre", "@types/jest": "26.0.15", - "@types/lodash": "4.14.149", "@types/react": "18.0.28", - "lodash": "4.17.21" + "copy-webpack-plugin": "11.0.0", + "eslint-webpack-plugin": "4.0.0", + "fork-ts-checker-webpack-plugin": "8.0.0", + "jest": "29.3.1", + "jest-environment-jsdom": "29.3.1", + "ts-jest": "29.0.5", + "ts-loader": "9.3.1", + "ts-node": "10.9.1", + "webpack": "5.76.0" }, "dependencies": { "@grafana/data": "10.0.0-pre", "@grafana/ui": "10.0.0-pre", - "jquery": "3.5.1", "react": "18.2.0", - "react-dom": "18.2.0", - "react-hook-form": "7.5.3", - "react-router-dom": "5.3.3", - "tslib": "2.4.0" + "tslib": "2.5.0" } } diff --git a/plugins-bundled/internal/input-datasource/tsconfig.json b/plugins-bundled/internal/input-datasource/tsconfig.json index a1bf2d01c58..2be6ec78f05 100644 --- a/plugins-bundled/internal/input-datasource/tsconfig.json +++ b/plugins-bundled/internal/input-datasource/tsconfig.json @@ -4,5 +4,13 @@ "compilerOptions": { "rootDir": "./src", "baseUrl": "./src" + }, + "ts-node": { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "esModuleInterop": true + }, + "transpileOnly": true } } diff --git a/plugins-bundled/internal/input-datasource/webpack.config.ts b/plugins-bundled/internal/input-datasource/webpack.config.ts new file mode 100644 index 00000000000..1620a0b9d4d --- /dev/null +++ b/plugins-bundled/internal/input-datasource/webpack.config.ts @@ -0,0 +1,146 @@ +import CopyWebpackPlugin from 'copy-webpack-plugin'; +import ESLintPlugin from 'eslint-webpack-plugin'; +import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; +import path from 'path'; +import { Configuration } from 'webpack'; + +const SOURCE_DIR = path.resolve(__dirname, 'src'); +const DIST_DIR = path.resolve(__dirname, 'dist'); +const PLUGIN_ID = require(path.join(SOURCE_DIR, 'plugin.json')).id; + +const config = async (env: Record): Promise => ({ + cache: { + type: 'filesystem', + buildDependencies: { + config: [__filename], + }, + }, + + context: path.join(process.cwd(), SOURCE_DIR), + + devtool: env.production ? 'source-map' : 'eval-source-map', + + entry: { + module: path.join(SOURCE_DIR, 'module.ts'), + }, + + externals: [ + 'lodash', + 'jquery', + 'moment', + 'slate', + 'emotion', + '@emotion/react', + '@emotion/css', + 'prismjs', + 'slate-plain-serializer', + '@grafana/slate-react', + 'react', + 'react-dom', + 'react-redux', + 'redux', + 'rxjs', + 'react-router', + 'react-router-dom', + 'd3', + 'angular', + '@grafana/ui', + '@grafana/runtime', + '@grafana/data', + + // Mark legacy SDK imports as external if their name starts with the "grafana/" prefix + ({ request }, callback) => { + const prefix = 'grafana/'; + const hasPrefix = (request: string) => request.indexOf(prefix) === 0; + const stripPrefix = (request: string) => request.substring(prefix.length); + + if (request && hasPrefix(request)) { + return callback(undefined, stripPrefix(request)); + } + + callback(); + }, + ], + + mode: env.production ? 'production' : 'development', + + module: { + rules: [ + { + exclude: /(node_modules)/, + test: /\.[tj]sx?$/, + use: { + loader: 'ts-loader', + }, + }, + { + test: /\.(png|jpe?g|gif|svg)$/, + type: 'asset/resource', + generator: { + // Keep publicPath relative for host.com/grafana/ deployments + publicPath: `public/plugins/${PLUGIN_ID}/img/`, + outputPath: 'img/', + filename: Boolean(env.production) ? '[hash][ext]' : '[name][ext]', + }, + }, + { + test: /\.(woff|woff2|eot|ttf|otf)(\?v=\d+\.\d+\.\d+)?$/, + type: 'asset/resource', + generator: { + // Keep publicPath relative for host.com/grafana/ deployments + publicPath: `public/plugins/${PLUGIN_ID}/fonts`, + outputPath: 'fonts/', + filename: Boolean(env.production) ? '[hash][ext]' : '[name][ext]', + }, + }, + ], + }, + + output: { + clean: { + keep: new RegExp(`.*?_(amd64|arm(64)?)(.exe)?`), + }, + filename: '[name].js', + library: { + type: 'amd', + }, + path: DIST_DIR, + publicPath: '/', + }, + + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: '../README.md', to: '.', force: true, context: SOURCE_DIR }, + { from: 'plugin.json', to: '.', context: SOURCE_DIR }, + { from: '**/*.json', to: '.', context: SOURCE_DIR }, + { from: '**/*.svg', to: '.', noErrorOnMissing: true, context: SOURCE_DIR }, // Optional + { from: '**/*.png', to: '.', noErrorOnMissing: true, context: SOURCE_DIR }, // Optional + { from: '**/*.html', to: '.', noErrorOnMissing: true, context: SOURCE_DIR }, // Optional + { from: 'img/**/*', to: '.', noErrorOnMissing: true, context: SOURCE_DIR }, // Optional + { from: 'libs/**/*', to: '.', noErrorOnMissing: true, context: SOURCE_DIR }, // Optional + { from: 'static/**/*', to: '.', noErrorOnMissing: true, context: SOURCE_DIR }, // Optional + ], + }), + new ForkTsCheckerWebpackPlugin({ + async: Boolean(env.development), + issue: { + include: [{ file: '**/*.{ts,tsx}' }], + }, + typescript: { configFile: path.join(process.cwd(), 'tsconfig.json') }, + }), + new ESLintPlugin({ + extensions: ['.ts', '.tsx'], + lintDirtyModulesOnly: Boolean(env.development), // don't lint on start, only lint changed files + }), + ], + + resolve: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + // handle resolving "rootDir" paths + modules: [path.resolve(process.cwd(), 'src'), 'node_modules'], + unsafeCache: true, + }, +}); + +export default config; diff --git a/yarn.lock b/yarn.lock index 20f98a90e43..a24b50d212f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3005,18 +3005,20 @@ __metadata: resolution: "@grafana-plugins/input-datasource@workspace:plugins-bundled/internal/input-datasource" dependencies: "@grafana/data": 10.0.0-pre - "@grafana/toolkit": 10.0.0-pre "@grafana/ui": 10.0.0-pre "@types/jest": 26.0.15 - "@types/lodash": 4.14.149 "@types/react": 18.0.28 - jquery: 3.5.1 - lodash: 4.17.21 + copy-webpack-plugin: 11.0.0 + eslint-webpack-plugin: 4.0.0 + fork-ts-checker-webpack-plugin: 8.0.0 + jest: 29.3.1 + jest-environment-jsdom: 29.3.1 react: 18.2.0 - react-dom: 18.2.0 - react-hook-form: 7.5.3 - react-router-dom: 5.3.3 - tslib: 2.4.0 + ts-jest: 29.0.5 + ts-loader: 9.3.1 + ts-node: 10.9.1 + tslib: 2.5.0 + webpack: 5.76.0 languageName: unknown linkType: soft @@ -3375,7 +3377,7 @@ __metadata: languageName: unknown linkType: soft -"@grafana/toolkit@10.0.0-pre, @grafana/toolkit@workspace:*, @grafana/toolkit@workspace:packages/grafana-toolkit": +"@grafana/toolkit@workspace:*, @grafana/toolkit@workspace:packages/grafana-toolkit": version: 0.0.0-use.local resolution: "@grafana/toolkit@workspace:packages/grafana-toolkit" dependencies: @@ -9760,13 +9762,6 @@ __metadata: languageName: node linkType: hard -"@types/lodash@npm:4.14.149": - version: 4.14.149 - resolution: "@types/lodash@npm:4.14.149" - checksum: 6caf68cf38d9672851490cdb0a9ef25a90495c05903ca16e62d1d78ebb8b12ee46b20c2a5e29b7667612baedca0087c10f56debc305e486aba08b3dbefb93865 - languageName: node - linkType: hard - "@types/lodash@npm:4.14.181": version: 4.14.181 resolution: "@types/lodash@npm:4.14.181" @@ -24036,13 +24031,6 @@ __metadata: languageName: node linkType: hard -"jquery@npm:3.5.1": - version: 3.5.1 - resolution: "jquery@npm:3.5.1" - checksum: 813047b852511ca1ecfaa7b2568aba1d7270a92e5c74962b308792a401adf041869a3b2a6858b0b7a02f6684947fb93171e40cbb4460831977a937b40b0e15ce - languageName: node - linkType: hard - "jquery@npm:3.6.3": version: 3.6.3 resolution: "jquery@npm:3.6.3"