Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for sku-telemetry #495

Merged
merged 9 commits into from
Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/lovely-buttons-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
'sku': patch
---

Add support for `@seek/sku-telemetry`.

To help improve sku, you should add this as a dev dependency:

```bash
$ yarn add --dev @seek/sku-telemetry
```
or

```bash
$ npm install --save-dev @seek/sku-telemetry
```
38 changes: 38 additions & 0 deletions config/webpack/plugins/metrics-plugin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const { performance } = require('perf_hooks');

const track = require('../../../../telemetry');

class MetricsPlugin {
constructor({ type, target }) {
this.initial = true;
this.target = target;
this.type = type;
}

apply(compiler) {
compiler.hooks.watchRun.tap('sku-metrics-plugin', () => {
this.startTime = performance.now();
});

compiler.hooks.done.tap('sku-metrics-plugin', () => {
if (this.initial) {
track.timing('start.webpack.initial', performance.now(), {
target: this.target,
type: this.type,
});
this.initial = false;
} else {
track.timing(
'start.webpack.rebuild',
performance.now() - this.startTime,
{
target: this.target,
type: this.type,
},
);
}
});
}
}

module.exports = MetricsPlugin;
8 changes: 8 additions & 0 deletions config/webpack/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const args = require('../args');
const config = require('../../context');
const { bundleAnalyzerPlugin } = require('./plugins/bundleAnalyzer');
const SkuWebpackPlugin = require('./plugins/sku-webpack-plugin');
const MetricsPlugin = require('./plugins/metrics-plugin');

const utils = require('./utils');
const debug = require('debug')('sku:webpack:config');
Expand Down Expand Up @@ -36,6 +37,7 @@ const makeWebpackConfig = ({
port = 0,
isDevServer = false,
htmlRenderPlugin,
metrics = false,
} = {}) => {
const isProductionBuild = process.env.NODE_ENV === 'production';

Expand Down Expand Up @@ -234,6 +236,9 @@ const makeWebpackConfig = ({
displayNamesProd,
MiniCssExtractPlugin,
}),
...(metrics
? [new MetricsPlugin({ type: 'static', target: 'browser' })]
: []),
],
},
{
Expand Down Expand Up @@ -287,6 +292,9 @@ const makeWebpackConfig = ({
displayNamesProd,
MiniCssExtractPlugin,
}),
...(metrics
? [new MetricsPlugin({ type: 'static', target: 'node' })]
: []),
],
},
].map(webpackDecorator);
Expand Down
3 changes: 3 additions & 0 deletions config/webpack/webpack.config.ssr.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const findUp = require('find-up');
const StartServerPlugin = require('start-server-webpack-plugin');
const LoadablePlugin = require('@loadable/webpack-plugin');
const SkuWebpackPlugin = require('./plugins/sku-webpack-plugin');
const MetricsPlugin = require('./plugins/metrics-plugin');

const debug = require('debug')('sku:webpack:config');
const args = require('../args');
Expand Down Expand Up @@ -185,6 +186,7 @@ const makeWebpackConfig = ({ clientPort, serverPort, isDevServer = false }) => {
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new MetricsPlugin({ type: 'ssr', target: 'browser' }),
]
: [
bundleAnalyzerPlugin({ name: 'client' }),
Expand Down Expand Up @@ -269,6 +271,7 @@ const makeWebpackConfig = ({ clientPort, serverPort, isDevServer = false }) => {
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new MetricsPlugin({ type: 'ssr', target: 'node' }),
]
: [],
),
Expand Down
39 changes: 39 additions & 0 deletions lib/banner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const chalk = require('chalk');
const wrap = require('wrap-ansi');
const identString = require('indent-string');

module.exports = (type, heading, messages = []) => {
let highlight;

switch (type) {
case 'error': {
highlight = chalk.red;
break;
}
case 'warning': {
highlight = chalk.yellow;
break;
}
default: {
throw new Error(`Banner type not implemented: ${type}`);
}
}

const formatedMessages = messages
.map((message) => identString(wrap(message, 80), 4))
.join('\n\n');

console.log(`
${highlight(
'-------------------------------------------------------------------------------------------',
)}

${chalk.bold(highlight(heading))}

${formatedMessages}

${highlight(
'-------------------------------------------------------------------------------------------',
)}
`);
};
32 changes: 12 additions & 20 deletions lib/validatePeersDeps.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,13 @@ const fs = require('fs-extra');
const glob = require('fast-glob');
const semver = require('semver');
const chalk = require('chalk');
const wrap = require('wrap-ansi');
const identString = require('indent-string');

const banner = require('./banner');
const track = require('../telemetry');
const detectYarn = require('./detectYarn');
const { cwd, getPathFromCwd } = require('../lib/cwd');
const { paths } = require('../context');

const bannerMessage = (heading, messages = []) => {
const formatedMessages = messages
.map((message) => identString(wrap(message, 80), 4))
.join('\n\n');

console.log(chalk`
{red -------------------------------------------------------------------------------------------}

{red.bold ${heading}}

${formatedMessages}

{red -------------------------------------------------------------------------------------------}
`);
};

const asyncMap = (list, fn) => {
return Promise.all(list.map((item) => fn(item)));
};
Expand Down Expand Up @@ -67,7 +52,10 @@ module.exports = async () => {
);
}

bannerMessage('Error: Duplicate packages detected', messages);
track.count('duplicate_compile_package', {
compile_package: compilePackage,
});
banner('error', 'Error: Duplicate packages detected', messages);
}

packages.push(...results);
Expand Down Expand Up @@ -98,6 +86,10 @@ module.exports = async () => {
const dep = compilePackages.get(peerName);

if (dep && !semver.satisfies(dep.version, peerVersionRange)) {
track.count('peer_dep_version_mismatch', {
compile_package: compilePackage,
});

const peerIsBehind = semver.gtr(dep.version, peerVersionRange);

const errorMessage = chalk`{bold ${packageName}} expected to find {bold ${peerName}} {yellow ${peerVersionRange}} but found {yellow ${dep.version}}.`;
Expand All @@ -106,7 +98,7 @@ module.exports = async () => {

const peerAheadMessage = chalk`The best way to fix this is to update your dependency on {bold ${peerName}}.`;

bannerMessage('Warning: Package version mismatch', [
banner('warning', 'Warning: Package version mismatch', [
errorMessage,
peerIsBehind ? peerBehindMessage : peerAheadMessage,
]);
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"lint": "npm run format-check && eslint .",
"check": "yarn check --integrity && echo 'Ignore paths from lint-staged'",
"pretest": "yarn check --integrity",
"test": "OPEN_TAB=false jest --verbose --detectOpenHandles --runInBand",
"test-manual": "node test/manual",
"test": "SKU_TELEMETRY=false OPEN_TAB=false jest --verbose --detectOpenHandles --runInBand",
"test-manual": "SKU_TELEMETRY=false node test/manual",
"setup-test-hosts": "node test/utils/setupTestHosts",
"format": "prettier --write '**/*.{js,ts,tsx,md,less,css}'",
"format-check": "prettier --list-different '**/*.{js,ts,tsx,md,less,css}'",
Expand Down Expand Up @@ -139,6 +139,7 @@
"postcss-js": "^2.0.2",
"postcss-loader": "^3.0.0",
"prettier": "2.0.2",
"pretty-ms": "^6.0.1",
"raw-loader": "^4.0.0",
"react-treat": "^1.0.2",
"rimraf": "^3.0.0",
Expand Down
21 changes: 17 additions & 4 deletions scripts/build-ssr.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// First, ensure the build is running in production mode
process.env.NODE_ENV = 'production';

const { performance } = require('perf_hooks');
const prettyMilliseconds = require('pretty-ms');
const webpack = require('webpack');
const { green, red } = require('chalk');
const { run } = require('../lib/runWebpack');
Expand All @@ -11,6 +13,7 @@ const {
} = require('../lib/buildFileUtils');
const makeWebpackConfig = require('../config/webpack/webpack.config.ssr');
const { port } = require('../context');
const track = require('../telemetry');

(async () => {
try {
Expand All @@ -24,10 +27,20 @@ const { port } = require('../context');
await run(webpack(serverConfig));
await copyPublicFiles();

console.log(green('Sku build complete!'));
} catch (e) {
console.error(red(e));
const timeTaken = performance.now();
track.timing('build', timeTaken, { status: 'success', type: 'ssr' });

process.exit(1);
console.log(
green(`Sku build complete in ${prettyMilliseconds(timeTaken)}`),
);
} catch (error) {
const timeTaken = performance.now();
track.timing('build', timeTaken, { status: 'failed', type: 'ssr' });

console.error(red(error));

process.exitCode = 1;
} finally {
await track.close();
}
})();
19 changes: 17 additions & 2 deletions scripts/build.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// First, ensure the build is running in production mode
process.env.NODE_ENV = 'production';

const prettyMilliseconds = require('pretty-ms');
const { green, red } = require('chalk');
const webpack = require('webpack');
const { performance } = require('perf_hooks');

const {
copyPublicFiles,
Expand All @@ -14,6 +16,7 @@ const { run } = require('../lib/runWebpack');
const createHtmlRenderPlugin = require('../config/webpack/plugins/createHtmlRenderPlugin');
const makeWebpackConfig = require('../config/webpack/webpack.config');
const { isLibrary } = require('../context');
const track = require('../telemetry');

(async () => {
try {
Expand All @@ -28,9 +31,21 @@ const { isLibrary } = require('../context');
);
await cleanRenderJs();
await copyPublicFiles();
console.log(green('Sku build complete!'));

const timeTaken = performance.now();
track.timing('build', timeTaken, { status: 'success', type: 'static' });

console.log(
green(`Sku build complete in ${prettyMilliseconds(timeTaken)}`),
);
} catch (error) {
const timeTaken = performance.now();
track.timing('build', timeTaken, { status: 'failed', type: 'static' });

console.error(red(error));
process.exit(1);

process.exitCode = 1;
} finally {
await track.close();
}
})();
3 changes: 3 additions & 0 deletions scripts/serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ const allocatePort = require('../lib/allocatePort');
const openBrowser = require('../lib/openBrowser');
const getSiteForHost = require('../lib/getSiteForHost');
const args = require('../config/args');
const track = require('../telemetry');

const environment = args.environment ? args.environment : environments[0] || '';
const prefferedSite = args.site;

(async () => {
track.count('serve');

const targetFolderExists = fs.existsSync(paths.target);

if (!targetFolderExists) {
Expand Down
8 changes: 7 additions & 1 deletion scripts/setup-hosts.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
const { setupHosts } = require('../lib/hosts');
const track = require('../telemetry');

(async () => {
try {
await setupHosts();
track.count('setup_hosts', { status: 'success' });
} catch (e) {
process.exit(1);
track.count('setup_hosts', { status: 'failed' });

process.exitCode = 1;
} finally {
await track.close();
}
})();
1 change: 1 addition & 0 deletions scripts/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const localhost = '0.0.0.0';
port: availablePort,
isDevServer: true,
htmlRenderPlugin,
metrics: true,
});

const parentCompiler = webpack(config);
Expand Down
25 changes: 25 additions & 0 deletions telemetry/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const os = require('os');

const { getPathFromCwd } = require('../lib/cwd');
const provider = require('./provider');
const skuVersion = require('../package.json').version;

let projectName = 'unknown';
try {
const packageJson = require(getPathFromCwd('package.json'));

if (packageJson.name) {
projectName = packageJson.name;
}
} catch (e) {}

const isCI = process.env.CI === 'true';

provider.addGlobalTags({
ci: isCI,
version: skuVersion,
project: projectName,
os: os.platform(),
});

module.exports = provider;