Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/renovate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
"@nx/eslint",
"@nx/jest",
"@nx/js",
"@nx/webpack",
"@types/chrome",
"@types/firefox-webext-browser",
"@types/glob",
Expand Down
86 changes: 86 additions & 0 deletions apps/cli/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"name": "cli",
"projectType": "application",
"sourceRoot": "apps/cli/src",
"tags": ["scope:cli", "type:app"],
"targets": {
"build": {
"executor": "@nx/webpack:webpack",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "oss-dev",
"options": {
"outputPath": "dist/apps/cli",
"webpackConfig": "apps/cli/webpack.config.js",
"tsConfig": "apps/cli/tsconfig.json",
"main": "apps/cli/src/bw.ts",
"target": "node",
"compiler": "tsc"
},
"configurations": {
"oss": {
"mode": "production",
"outputPath": "dist/apps/cli/oss"
},
"oss-dev": {
"mode": "development",
"outputPath": "dist/apps/cli/oss-dev"
},
"commercial": {
"mode": "production",
"outputPath": "dist/apps/cli/commercial",
"webpackConfig": "bitwarden_license/bit-cli/webpack.config.js",
"main": "bitwarden_license/bit-cli/src/bw.ts",
"tsConfig": "bitwarden_license/bit-cli/tsconfig.json"
},
"commercial-dev": {
"mode": "development",
"outputPath": "dist/apps/cli/commercial-dev",
"webpackConfig": "bitwarden_license/bit-cli/webpack.config.js",
"main": "bitwarden_license/bit-cli/src/bw.ts",
"tsConfig": "bitwarden_license/bit-cli/tsconfig.json"
}
}
},
"serve": {
"executor": "@nx/webpack:webpack",
"defaultConfiguration": "oss-dev",
"options": {
"outputPath": "dist/apps/cli",
"webpackConfig": "apps/cli/webpack.config.js",
"tsConfig": "apps/cli/tsconfig.json",
"main": "apps/cli/src/bw.ts",
"target": "node",
"compiler": "tsc",
"watch": true
},
"configurations": {
"oss-dev": {
"mode": "development",
"outputPath": "dist/apps/cli/oss-dev"
},
"commercial-dev": {
"mode": "development",
"outputPath": "dist/apps/cli/commercial-dev",
"webpackConfig": "bitwarden_license/bit-cli/webpack.config.js",
"main": "bitwarden_license/bit-cli/src/bw.ts",
"tsConfig": "bitwarden_license/bit-cli/tsconfig.json"
}
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "apps/cli/jest.config.js"
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/cli/**/*.ts"]
}
}
}
}
36 changes: 29 additions & 7 deletions apps/cli/webpack.base.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: instead of putting the default values interspersed in the code

patterns: [{ from: params.localesPath || "./src/locales", to: "locales" }],

could we move it all to one place?

const DEFAULT_PARAMS = {
  outputPath: "...",
  mode: "...",
  env: "...",
  modulesPath: [],
  localesPath: "...",
  externalsModulesDir: "...",
  watch: "...",
};

module.exports.buildConfig = function buildConfig(params) {
  params = { ...DEFAULT_PARAMS, params };

Copy link
Contributor Author

@addisonbeck addisonbeck Oct 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Really cleans this up a lot. Implemented as suggested on a72cd0e.

Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,32 @@ module.exports.getEnv = function getEnv() {
return { ENV };
};

const DEFAULT_PARAMS = {
localesPath: "./src/locales",
modulesPath: [path.resolve("../../node_modules")],
externalsModulesDir: "../../node_modules",
outputPath: path.resolve(__dirname, "build"),
watch: false,
};

/**
*
* @param {{
* configName: string;
* entry: string;
* tsConfig: string;
* outputPath?: string;
* mode?: string;
* env?: string;
* modulesPath?: string[];
* localesPath?: string;
* externalsModulesDir?: string;
* watch?: boolean;
* }} params
*/
module.exports.buildConfig = function buildConfig(params) {
const { ENV } = module.exports.getEnv();
params = { ...DEFAULT_PARAMS, ...params };
const ENV = params.env || module.exports.getEnv().ENV;

const envConfig = config.load(ENV);
config.log(`Building CLI - ${params.configName} version`);
Expand All @@ -35,7 +51,7 @@ module.exports.buildConfig = function buildConfig(params) {

const plugins = [
new CopyWebpackPlugin({
patterns: [{ from: "./src/locales", to: "locales" }],
patterns: [{ from: params.localesPath, to: "locales" }],
}),
new webpack.DefinePlugin({
"process.env.BWCLI_ENV": JSON.stringify(ENV),
Expand All @@ -61,7 +77,7 @@ module.exports.buildConfig = function buildConfig(params) {
];

const webpackConfig = {
mode: ENV,
mode: params.mode || ENV,
target: "node",
devtool: ENV === "development" ? "eval-source-map" : "source-map",
node: {
Expand All @@ -77,26 +93,32 @@ module.exports.buildConfig = function buildConfig(params) {
resolve: {
extensions: [".ts", ".js"],
symlinks: false,
modules: [path.resolve("../../node_modules")],
modules: params.modulesPath,
plugins: [new TsconfigPathsPlugin({ configFile: params.tsConfig })],
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "build"),
path: path.resolve(params.outputPath),
clean: true,
},
module: { rules: moduleRules },
plugins: plugins,
externals: [
nodeExternals({
modulesDir: "../../node_modules",
modulesDir: params.externalsModulesDir,
allowlist: [/@bitwarden/],
}),
],
experiments: {
asyncWebAssembly: true,
},
};

if (params.watch) {
webpackConfig.watch = true;
webpackConfig.watchOptions = {
ignored: /node_modules/,
poll: 1000,
};
}
return webpackConfig;
};
51 changes: 46 additions & 5 deletions apps/cli/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,48 @@
const path = require("path");
const { buildConfig } = require("./webpack.base");

module.exports = buildConfig({
configName: "OSS",
entry: "./src/bw.ts",
tsConfig: "./tsconfig.json",
});
module.exports = (webpackConfig, context) => {
// Detect if called by Nx (context parameter exists)
const isNxBuild = context && context.options;

if (isNxBuild) {
// Nx build configuration
const mode = context.options.mode || "development";
if (process.env.NODE_ENV == null) {
process.env.NODE_ENV = mode;
}
const ENV = (process.env.ENV = process.env.NODE_ENV);

return buildConfig({
configName: "OSS",
entry: context.options.main || "apps/cli/src/bw.ts",
tsConfig: "tsconfig.base.json",
outputPath: path.resolve(context.context.root, context.options.outputPath),
mode: mode,
env: ENV,
modulesPath: [path.resolve("node_modules")],
localesPath: "apps/cli/src/locales",
externalsModulesDir: "node_modules",
watch: context.options.watch || false,
});
} else {
// npm build configuration
if (process.env.NODE_ENV == null) {
process.env.NODE_ENV = "development";
}
const ENV = (process.env.ENV = process.env.NODE_ENV);
const mode = ENV;

return buildConfig({
configName: "OSS",
entry: "./src/bw.ts",
tsConfig: "./tsconfig.json",
outputPath: path.resolve(__dirname, "build"),
mode: mode,
env: ENV,
modulesPath: [path.resolve("../../node_modules")],
localesPath: "./src/locales",
externalsModulesDir: "../../node_modules",
});
Comment on lines +36 to +46
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of these are the default values in webpack.base, but they won't be for long so I was verbose with these args.

}
};
51 changes: 46 additions & 5 deletions bitwarden_license/bit-cli/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,48 @@
const path = require("path");
const { buildConfig } = require("../../apps/cli/webpack.base");

module.exports = buildConfig({
configName: "Commercial",
entry: "../../bitwarden_license/bit-cli/src/bw.ts",
tsConfig: "../../bitwarden_license/bit-cli/tsconfig.json",
});
module.exports = (webpackConfig, context) => {
// Detect if called by Nx (context parameter exists)
const isNxBuild = context && context.options;

if (isNxBuild) {
// Nx build configuration
const mode = context.options.mode || "development";
if (process.env.NODE_ENV == null) {
process.env.NODE_ENV = mode;
}
const ENV = (process.env.ENV = process.env.NODE_ENV);

return buildConfig({
configName: "Commercial",
entry: context.options.main || "bitwarden_license/bit-cli/src/bw.ts",
tsConfig: "tsconfig.base.json",
outputPath: path.resolve(context.context.root, context.options.outputPath),
mode: mode,
env: ENV,
modulesPath: [path.resolve("node_modules")],
localesPath: "apps/cli/src/locales",
externalsModulesDir: "node_modules",
watch: context.options.watch || false,
});
} else {
// npm build configuration
if (process.env.NODE_ENV == null) {
process.env.NODE_ENV = "development";
}
const ENV = (process.env.ENV = process.env.NODE_ENV);
const mode = ENV;

return buildConfig({
configName: "Commercial",
entry: "../../bitwarden_license/bit-cli/src/bw.ts",
tsConfig: "../../bitwarden_license/bit-cli/tsconfig.json",
outputPath: path.resolve(__dirname, "../../apps/cli/build"),
mode: mode,
env: ENV,
modulesPath: [path.resolve("../../node_modules")],
localesPath: "../../apps/cli/src/locales",
externalsModulesDir: "../../node_modules",
});
}
};
Loading
Loading