Build Pipeline Integration
As explained in the "Dynamic Analysis" chapter: for Dbux to work, it first needs to record JavaScript application behavior. To that end, your program must be instrumented with @dbux/babel-plugin (i.e.: you need to "babel your program" with @dbux/babel-plugin
enabled).
Once running, the injected @dbux/runtime
will send collected data to the runtime server.
Setup
First npm install
or yarn add
the necessary @dbux
packages to the project you want to trace:
@dbux/babel-plugin
@dbux/runtime
Alternatively, simply install @dbux/cli. That will also install the other necessary dependencies.
Important: Make sure, that they match the version of Dbux VSCode Extension that you installed.
Config
You can find configuration options for the different tools in the "Tools and Configuration" chapter.
In addition to configuring the individual tools, you want to make sure you configure the module filter to trace the right files.
Node Applications
For Node applications that do not need bundling or building, refer to the Dbux CLI documentation.
Webpack
Example:
const makeInclude = require('@dbux/common-node/dist/filters/makeInclude').default;
const moduleFilterOptions = {
packageWhitelist: 'interestingPackage1,@interesting/package2',
// packageBlacklist: '',
fileBlacklist: '.*bad_file1\.js,.*/unwanted_dir1/.*'
};
// ...
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.jsx?$/,
include: [
makeInclude(moduleFilterOptions)
],
use: {
loader: 'babel-loader',
options: {
/**
* Make sure, things work correctly, even if babeling (maybe previously unbabled) `node_modules`.
* @see https://github.com/webpack/webpack/issues/4039#issuecomment-419284940
*/
sourceType: 'unambiguous',
plugins: [
// other plugins, running **after** Dbux...
'@dbux/babel-plugin'
// other plugins, running **before** Dbux...
]
}
}
}
]
}
};
NOTE: For Dbux Practice projects, we use the (configurable/flexible/complicated) dbux.webpack.config.base.js.
Debugging Webpack w/ Dbux
Sometimes, you want to debug your webpack.config.js
, or webpack
, in general, using Dbux.
This is the command to do that:
npx dbux run ../node_modules/webpack-cli/bin/cli.js -- webpack args here
# or, if you want to debug webpack itself:
npx dbux run --pw=webpack.*,tapable,graceful-fs,enhanced-resolve ../node_modules/webpack-cli/bin/cli.js -- webpack args here
Keep an eye out for the following pitfalls:
webpack
adds a layer of@babel/register
.- Because of that: webpack will run itself with the default babel config of the project. That usually does not affect anything, but there are buggy edge cases, and that's worth noting.
- Also, if you run that
webpack
project with Dbux enabled, Dbux adds a second layer of@babel/register
. So it will double up. That is generally not a problem, but attentions is warranted.- You want to make sure that
webpack
itself does not read ababel
config which in turn adds@dbux/babel-plugin
(which the project default babel config is likely to do). - NOTE: If you don't run
webpack
with Dbux enabled, it is all fine.
- You want to make sure that
webpack
uses few libraries that themselves are very heavy on instrumentation. Since Dbux also instruments things, you end up having one instrumenter trying to instrument another. That can lead to problems.- If you want to understand the inner workings of
webpack
, we found the following whitelist to work quite well:--pw=webpack.*,tapable,graceful-fs,enhanced-resolve
- If you want to understand the inner workings of
Rollup
TODO: We have not tested this in a while. Need to verify and set it in stone. Test with the previously working Chart.js
practice exercises (which uses Rollup).
Rollup requires use of @rollup/plugin-babel.
Example - something like this:
const makeInclude = require('@dbux/common-node/dist/filters/makeInclude').default;
const moduleFilterOptions = {
packageWhitelist: 'interestingPackage1,@interesting/package2',
// packageBlacklist: '',
fileBlacklist: '.*bad_file1\.js,.*/unwanted_dir1/.*'
};
const config = {
...
plugins: [
babel({
babelHelpers: 'inline',
filter: makeInclude(moduleFilterOptions),
/**
* WARNING: if not skipped, we saw some serious memory leaks (in 2020), but might already be fixed in 2022.
* TODO: we need to test this again.
*/
skipPreflightCheck: true
})
]
};
Storybook
TODO
Create-React-App
TODO: Clean this up
install
CRACO
$ yarn add --dev @craco/craco
Fix
package.json
to usecraco
instead ofreact-scripts
:/* package.json */
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test"
}Customize webpack config with
CRACO
: Example - something like this:// craco.config.js
const { getLoaders, loaderByName } = require('@craco/craco');
const dbuxOptions = {
moduleFilter: {
packageWhitelist: '.*',
/**
* NOTE: these libraries might run before dbux is initialized, so they must be blacklisted.
* 1. Some hook themsleves into webpack.
* 2. The later ones are polyfills (probably brought in by CRA) and their libraries; loaded when first requiring things, and before `@dbux/runtime`.
*/
packageBlacklist: 'react-dev-utils,react-refresh,react-error-overlay,process,buffer,isarray,ieee754,base64-js',
fileWhitelist: '.*',
// we generally do not want to mess with production or webpack code
fileBlacklist: '.*production.*,.*[wW]ebpack.*'
}
};
module.exports = {
webpack: {
configure: (webpackConfig, { env, paths }) => {
const { hasFoundAny, matches } = getLoaders(webpackConfig, loaderByName("babel-loader"));
// // TODO: write output files (this won't work, `devServer` does not exit)
// webpackConfig.devServer.devMiddleware.writeToDisk = true;
// // exclude dbux from all rules
// const reported = new Set();
// webpackConfig.module.rules.forEach(rule => {
// if (rule.exclude && !Array.isArray(rule.exclude)) {
// rule.exclude = [rule.exclude];
// }
// if (!rule.exclude) {
// rule.exclude = [];
// }
// rule.exclude.push((modulePath) => {
// const exclude = modulePath.includes('@dbux');
// if (!reported.has(modulePath)) {
// reported.add(modulePath);
// console.debug(`[WEBPACK]`, modulePath, !exclude);
// }
// return exclude;
// });
// });
// add dbux to loader
if (hasFoundAny) {
matches.forEach(match => {
const babelOptions = match.loader.options;
if (!babelOptions.plugins) {
babelOptions.plugins = [];
}
// NOTE: weird bug with a class having public fields (in @dbux/runtime) that Babel complains about
babelOptions.plugins.push(['@babel/plugin-proposal-class-properties', { loose: true }]);
babelOptions.plugins.push(['@dbux/babel-plugin', dbuxOptions]);
});
console.debug(`Added @dbux/babel-plugin to babel-loaders.`);
}
else {
throw new Error(`Could not inject Dbux: 'babel-loader' found`);
}
return webpackConfig;
}
},
};
Next.js
TODO
ng
TODO
Other Bundlers or Bundler Wrappers
TODO