Skip to content

Commit

Permalink
chore: speed up local dev (grafana#686)
Browse files Browse the repository at this point in the history
* fix type errors

* chore: speed up tests

as per kulshekhar/ts-jest#259 (comment)
using maxWorkers: 1 ends up being faster

* set typescript to only build the webapp/javascript dir

* use a specific tsconfig just for linting

* speed up tests

* lint test files as well

* use esbuild

* optimize local refresh by only building the index page

* print to stderr from webpack to make it easier to save stats

* inject livereload script to index.html

* fix prod build by enabling ts-jest
  • Loading branch information
eh-am authored and juliosaraiva committed Jan 16, 2022
1 parent d89bec0 commit 1194e81
Show file tree
Hide file tree
Showing 14 changed files with 487 additions and 639 deletions.
16 changes: 14 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ module.exports = {
},
env: {
browser: true,
node: true,
// node: true,
jquery: true,
},
parserOptions: {
project: './tsconfig.json',
project: './tsconfig.eslint.json',
},
settings: {
'import/resolver': {
Expand All @@ -74,4 +74,16 @@ module.exports = {
},
},
},
overrides: [
// Tests are completely different
// And we shouldn't be so strict
{
files: ['**/?(*.)+(spec|test).+(ts|tsx|js)'],
plugins: ['jest'],
env: {
node: true,
'jest/globals': true,
},
},
],
};
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module.exports = {
],
globals: {
'ts-jest': {
tsconfig: `tsconfig.test.json`,
diagnostics: {
// https://github.com/kulshekhar/ts-jest/issues/1647#issuecomment-832577036
pathRegex: /\.(test)\.tsx$/,
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"build": "NODE_ENV=production webpack --config scripts/webpack/webpack.prod.ts",
"build:panel": "NODE_ENV=production webpack --config scripts/webpack/webpack.panel.ts",
"build:size-limit": "NODE_ENV=production webpack --config scripts/webpack/webpack.size-limit.ts",
"test": "jest",
"test": "jest --runInBand",
"test:ss": "UPDATE_SNAPSHOTS=true ./scripts/jest-snapshots/run-docker.sh",
"test:ss-check": "./scripts/jest-snapshots/run-docker.sh",
"lint": "eslint ./ --ext .js,.jsx,.ts,.tsx --cache --fix",
Expand Down Expand Up @@ -87,6 +87,7 @@
"eslint-plugin-css-modules": "^2.11.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^25.3.4",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-react": "^7.21.5",
Expand All @@ -97,7 +98,6 @@
"jest-canvas-mock": "^2.3.1",
"jest-css-modules-transform": "^4.3.0",
"jest-image-snapshot": "^4.5.1",
"koa-route": "^3.2.0",
"lint-staged": "^11.1.2",
"monaco-editor-webpack-plugin": "^1.9.0",
"optimize-css-assets-webpack-plugin": "^6.0.1",
Expand All @@ -108,15 +108,14 @@
"sass": "^1.26.10",
"size-limit": "^6.0.3",
"svg-jest": "^1.0.1",
"sync-request": "^6.1.0",
"ts-jest": "^27.0.5",
"typescript": "^4.5.2",
"typescript-plugin-css-modules": "^3.4.0",
"webpack": "^5.64.0",
"webpack-bundle-analyzer": "^4.4.2",
"webpack-livereload-plugin": "^3.0.2",
"webpack-merge": "^5.0.9",
"webpack-plugin-hash-output": "^3.2.1",
"webpack-plugin-serve": "^1.5.0"
"webpack-plugin-hash-output": "^3.2.1"
},
"dependencies": {
"@babel/plugin-transform-runtime": "^7.16.4",
Expand Down Expand Up @@ -149,6 +148,7 @@
"copy-webpack-plugin": "^6.3.2",
"css-loader": "^4.0.0",
"date-fns": "^2.27.0",
"esbuild-loader": "^2.18.0",
"eslint-import-resolver-webpack": "^0.13.2",
"file-loader": "^6.2.0",
"glob": "^7.1.7",
Expand Down
59 changes: 33 additions & 26 deletions scripts/webpack/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,35 +61,42 @@ export function getJsLoader() {
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
loader: 'esbuild-loader',
options: {
cacheDirectory: true,
babelrc: true,

plugins: ['@babel/plugin-transform-runtime'],
// Note: order is bottom-to-top and/or right-to-left
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: 'last 3 versions',
},
useBuiltIns: 'entry',
corejs: 3,
modules: false,
},
],
[
'@babel/preset-typescript',
{
allowNamespaces: true,
},
],
'@babel/preset-react',
],
loader: 'tsx', // Or 'ts' if you don't need tsx
target: 'es2015',
},
},
// {
// loader: 'babel-loader',
// options: {
// cacheDirectory: true,
// babelrc: true,
//
// plugins: ['@babel/plugin-transform-runtime'],
// // Note: order is bottom-to-top and/or right-to-left
// presets: [
// [
// '@babel/preset-env',
// {
// targets: {
// browsers: 'last 3 versions',
// },
// useBuiltIns: 'entry',
// corejs: 3,
// modules: false,
// },
// ],
// [
// '@babel/preset-typescript',
// {
// allowNamespaces: true,
// },
// ],
// '@babel/preset-react',
// ],
// },
// },
],
},
];
Expand Down
26 changes: 21 additions & 5 deletions scripts/webpack/webpack.common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,23 @@ import fs from 'fs';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import CopyPlugin from 'copy-webpack-plugin';
import { ESBuildMinifyPlugin } from 'esbuild-loader';

import { getAlias, getJsLoader, getStyleLoaders } from './shared';

const pages = glob
.sync('./webapp/templates/*.html')
// Most of the cases we will be developing the SPA
// So it makes sense only building it
// We go from
// [webpack.Progress] | | 1131 ms asset processing > HtmlWebpackPlugin
// To [webpack.Progress] | | 215 ms asset processing > HtmlWebpackPlugin
.sync(
process.env.NODE_ENV === 'production'
? './webapp/templates/*.html'
: './webapp/templates/index.html'
)
.map((x) => path.basename(x));

const pagePlugins = pages.map(
(name) =>
new HtmlWebpackPlugin({
Expand Down Expand Up @@ -68,6 +79,15 @@ export default {
ignored: /node_modules/,
},

optimization: {
minimizer: [
new ESBuildMinifyPlugin({
target: 'es2015',
css: true,
}),
],
},

module: {
// Note: order is bottom-to-top and/or right-to-left
rules: [
Expand Down Expand Up @@ -100,10 +120,6 @@ export default {
new MiniCssExtractPlugin({
filename: '[name].[hash].css',
}),
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}),
new CopyPlugin({
patterns: [
{
Expand Down
90 changes: 3 additions & 87 deletions scripts/webpack/webpack.dev.ts
Original file line number Diff line number Diff line change
@@ -1,97 +1,13 @@
import { merge } from 'webpack-merge';
import { WebpackPluginServe } from 'webpack-plugin-serve';
import path from 'path';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import request from 'sync-request';
import fs from 'fs';
import route from 'koa-route';
import LiveReloadPlugin from 'webpack-livereload-plugin';
import common from './webpack.common';

module.exports = merge(common, {
devtool: 'eval-source-map',
mode: 'development',
entry: {
serve: 'webpack-plugin-serve/client',
},

plugins: [
// create a server on port 4041 with live reload
// it will serve all static assets com webapp/public/assets
// and for the endpoints it will redirect to the go server (on port 4040)
new WebpackPluginServe({
port: 4041,
static: path.resolve(__dirname, '../../webapp/public'),
liveReload: true,
waitForBuild: true,
middleware: (app, builtins) => {
// TODO
// this sucks, maybe update endpoints to prefix with /api?
app.use(builtins.proxy('/render', { target: 'http://localhost:4040' }));
app.use(
builtins.proxy('/render-diff', { target: 'http://localhost:4040' })
);
app.use(builtins.proxy('/labels', { target: 'http://localhost:4040' }));
app.use(
builtins.proxy('/labels-diff', { target: 'http://localhost:4040' })
);
app.use(
builtins.proxy('/label-values', { target: 'http://localhost:4040' })
);

// New Endpoints are implemented under /api
app.use(builtins.proxy('/api', { target: 'http://localhost:4040' }));

// serve index for all pages
// that are not static (.css, .js) nor live reload (/wps)
// TODO: simplify this
app.use(
route.get(/^(.(?!(\.js|\.css|\.svg|wps)$))+$/, (ctx) => {
ctx.body = fs.readFileSync(
path.resolve(__dirname, '../../webapp/public/assets/index.html'),
{
encoding: 'utf-8',
}
);
})
);
},
}),

// serve index.html from the go server
// and additionally inject anything else required (eg livereload ws)
new HtmlWebpackPlugin({
publicPath: '/assets',
templateContent: () => {
let res;

// TODO: accept this to be overwritten?
// that's useful for when running on a different port (when you are running multiple pyroscope versions locally)
// or when running on ipv6
const goServerAddr = 'http://localhost:4040';

try {
console.log(`Trying to access go server on ${goServerAddr}`);

// makes a request against the go server to retrieve its index.html
// it assumes the server will either not respond or respond with 2xx
// (ie it doesn't handle != 2xx status codes)
// https://www.npmjs.com/package/sync-request
res = request('GET', goServerAddr, {
timeout: 1000,
maxRetries: 30,
retryDelay: 1000,
retry: true,
});
} catch (e) {
throw new Error(
`Could not find pyroscope instance running on ${goServerAddr}. Make sure you have pyroscope server running on port :4040`
);
}

console.log('Live reload server is up');

return res.getBody('utf8');
},
new LiveReloadPlugin({
appendScriptTag: true,
}),
],
// TODO deal with these types
Expand Down
7 changes: 7 additions & 0 deletions tsconfig.eslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"include": ["."],
// Since we excluded the test files in the main tsconfig.json
// We must renable them by explicitly setting an 'exclude'
"exclude": ["node_modules"]
}
16 changes: 15 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,27 @@
"esModuleInterop": true,
"sourceMap": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"paths": {
"@utils/*": ["./webapp/javascript/util/*"],
"@models/*": ["./webapp/javascript/models/*"],
"@ui/*": ["./webapp/javascript/ui/*"],
"@pyroscope/redux/*": ["./webapp/javascript/redux/*"]
},
"types": ["node"],
"plugins": [{ "name": "typescript-plugin-css-modules" }]
},
"exclude": ["node_modules"]
// ts-node is currently only used by webpack
"ts-node": {
"compilerOptions": {
"module": "CommonJS"
}
},
"include": ["./webapp/javascript/"],
"exclude": [
"webapp/javascript/**/*.spec.ts",
"webapp/javascript/**/*.spec.tsx",
"**/node_modules",
"**/.*/"
]
}
8 changes: 8 additions & 0 deletions tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"skipLibCheck": true,
"types": ["jest", "mocha", "@testing-library/jest-dom"],
"sourceMap": false
}
}
9 changes: 9 additions & 0 deletions webapp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,12 @@ To be able to do that, you need to add the alias to the following files:
* `scripts/webpack/webpack.common.js`
* `tsconfig.json`
* `jest.config.js`

# Developing the webapp/templates page
By default, developing pages other than the index require a bit of setup:


For example, acessing http://locahlost:4040/forbidden won't work
To be able to access it, update the variable `pages` in `scripts/webpack.common.ts` to allow building all pages when in dev mode.

Beware, this will make the (local) build slower.
6 changes: 5 additions & 1 deletion webapp/javascript/components/FileUploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export default function FileUploader({ file, setFile, className }: Props) {
reader.onload = () => {
const binaryStr = reader.result;

if (typeof binaryStr === 'string') {
throw new Error('Expecting file in binary format but got a string');
}

try {
// ArrayBuffer -> JSON
const s = JSON.parse(
Expand Down Expand Up @@ -85,7 +89,7 @@ export default function FileUploader({ file, setFile, className }: Props) {
</div>
{file && (
<aside>
Currently analyzing file {file.path}
Currently analyzing file {file.name}
&nbsp;
<Button icon={faTrash} onClick={onRemove}>
Remove
Expand Down
Loading

0 comments on commit 1194e81

Please sign in to comment.