mirror of
https://github.com/bitwarden/browser
synced 2026-02-05 03:03:26 +00:00
feat(cli): integrate Nx with CLI application
- Add project.json with build, serve, test, and lint targets - Support both OSS and Bit configurations via Nx configurations - Maintain backward compatibility with existing npm build scripts - Update webpack configs to work with both Nx and direct webpack CLI calls - Enable nx build cli --configuration=[oss|oss-dev|bit|bit-dev] commands - Enable nx serve cli for development workflow with watch mode - Preserve all existing npm run build:* commands for compatibility
This commit is contained in:
80
apps/cli/project.json
Normal file
80
apps/cli/project.json
Normal file
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"$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",
|
||||
"options": {
|
||||
"outputPath": "dist/apps/cli",
|
||||
"webpackConfig": "apps/cli/webpack.nx.config.js",
|
||||
"tsConfig": "apps/cli/tsconfig.json",
|
||||
"main": "apps/cli/src/bw.ts",
|
||||
"target": "node",
|
||||
"compiler": "tsc"
|
||||
},
|
||||
"configurations": {
|
||||
"oss": {
|
||||
"mode": "production"
|
||||
},
|
||||
"oss-dev": {
|
||||
"mode": "development"
|
||||
},
|
||||
"bit": {
|
||||
"mode": "production",
|
||||
"webpackConfig": "bitwarden_license/bit-cli/webpack.config.js",
|
||||
"main": "bitwarden_license/bit-cli/src/bw.ts",
|
||||
"tsConfig": "bitwarden_license/bit-cli/tsconfig.json"
|
||||
},
|
||||
"bit-dev": {
|
||||
"mode": "development",
|
||||
"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.nx.config.js",
|
||||
"tsConfig": "apps/cli/tsconfig.json",
|
||||
"main": "apps/cli/src/bw.ts",
|
||||
"target": "node",
|
||||
"compiler": "tsc",
|
||||
"watch": true
|
||||
},
|
||||
"configurations": {
|
||||
"oss-dev": {
|
||||
"mode": "development"
|
||||
},
|
||||
"bit-dev": {
|
||||
"mode": "development",
|
||||
"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"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,89 +1,2 @@
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const nodeExternals = require("webpack-node-externals");
|
||||
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
|
||||
const config = require("./config/config");
|
||||
|
||||
if (process.env.NODE_ENV == null) {
|
||||
process.env.NODE_ENV = "development";
|
||||
}
|
||||
const ENV = (process.env.ENV = process.env.NODE_ENV);
|
||||
|
||||
const envConfig = config.load(ENV);
|
||||
config.log(envConfig);
|
||||
|
||||
const moduleRules = [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
use: "ts-loader",
|
||||
exclude: path.resolve(__dirname, "node_modules"),
|
||||
},
|
||||
];
|
||||
|
||||
const plugins = [
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [{ from: "./src/locales", to: "locales" }],
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
"process.env.BWCLI_ENV": JSON.stringify(ENV),
|
||||
}),
|
||||
new webpack.BannerPlugin({
|
||||
banner: "#!/usr/bin/env node",
|
||||
raw: true,
|
||||
}),
|
||||
new webpack.IgnorePlugin({
|
||||
resourceRegExp: /^encoding$/,
|
||||
contextRegExp: /node-fetch/,
|
||||
}),
|
||||
new webpack.EnvironmentPlugin({
|
||||
ENV: ENV,
|
||||
BWCLI_ENV: ENV,
|
||||
FLAGS: envConfig.flags,
|
||||
DEV_FLAGS: envConfig.devFlags,
|
||||
}),
|
||||
new webpack.IgnorePlugin({
|
||||
resourceRegExp: /canvas/,
|
||||
contextRegExp: /jsdom$/,
|
||||
}),
|
||||
];
|
||||
|
||||
const webpackConfig = {
|
||||
mode: ENV,
|
||||
target: "node",
|
||||
devtool: ENV === "development" ? "eval-source-map" : "source-map",
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false,
|
||||
},
|
||||
entry: {
|
||||
bw: "./src/bw.ts",
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".ts", ".js"],
|
||||
symlinks: false,
|
||||
modules: [path.resolve("../../node_modules")],
|
||||
plugins: [new TsconfigPathsPlugin({ configFile: "./tsconfig.json" })],
|
||||
},
|
||||
output: {
|
||||
filename: "[name].js",
|
||||
path: path.resolve(__dirname, "build"),
|
||||
clean: true,
|
||||
},
|
||||
module: { rules: moduleRules },
|
||||
plugins: plugins,
|
||||
externals: [
|
||||
nodeExternals({
|
||||
modulesDir: "../../node_modules",
|
||||
allowlist: [/@bitwarden/],
|
||||
}),
|
||||
],
|
||||
experiments: {
|
||||
asyncWebAssembly: true,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = webpackConfig;
|
||||
// For backward compatibility with existing npm scripts
|
||||
module.exports = require("./webpack.npm.config.js");
|
||||
|
||||
23
apps/cli/webpack.npm.config.js
Normal file
23
apps/cli/webpack.npm.config.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const path = require("path");
|
||||
const { getSharedConfig } = require("./webpack.shared");
|
||||
|
||||
// Original npm/webpack CLI logic
|
||||
if (process.env.NODE_ENV == null) {
|
||||
process.env.NODE_ENV = "development";
|
||||
}
|
||||
const ENV = (process.env.ENV = process.env.NODE_ENV);
|
||||
const mode = ENV;
|
||||
|
||||
// npm-specific path configuration
|
||||
const options = {
|
||||
env: ENV,
|
||||
mode: mode,
|
||||
entryPoint: "./src/bw.ts",
|
||||
outputPath: path.resolve(__dirname, "build"),
|
||||
modulesPath: [path.resolve("../../node_modules")],
|
||||
tsconfigPath: "./tsconfig.json",
|
||||
localesPath: "./src/locales",
|
||||
externalsModulesDir: "../../node_modules",
|
||||
};
|
||||
|
||||
module.exports = getSharedConfig(options);
|
||||
25
apps/cli/webpack.nx.config.js
Normal file
25
apps/cli/webpack.nx.config.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const path = require("path");
|
||||
const { getSharedConfig } = require("./webpack.shared");
|
||||
|
||||
module.exports = (webpackConfig, context) => {
|
||||
// Set environment based on context mode
|
||||
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);
|
||||
|
||||
// Nx-specific path configuration
|
||||
const options = {
|
||||
env: ENV,
|
||||
mode: mode,
|
||||
entryPoint: context.options.main || "apps/cli/src/bw.ts",
|
||||
outputPath: path.resolve(context.context.root, context.options.outputPath),
|
||||
modulesPath: [path.resolve("node_modules")],
|
||||
tsconfigPath: "tsconfig.base.json",
|
||||
localesPath: "apps/cli/src/locales",
|
||||
externalsModulesDir: "node_modules",
|
||||
};
|
||||
|
||||
return getSharedConfig(options);
|
||||
};
|
||||
110
apps/cli/webpack.shared.js
Normal file
110
apps/cli/webpack.shared.js
Normal file
@@ -0,0 +1,110 @@
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const nodeExternals = require("webpack-node-externals");
|
||||
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
|
||||
const config = require("./config/config");
|
||||
|
||||
const getSharedConfig = (options) => {
|
||||
const {
|
||||
env,
|
||||
mode,
|
||||
entryPoint,
|
||||
outputPath,
|
||||
modulesPath,
|
||||
tsconfigPath,
|
||||
localesPath,
|
||||
externalsModulesDir,
|
||||
} = options;
|
||||
|
||||
const envConfig = config.load(env);
|
||||
config.log(envConfig);
|
||||
|
||||
return {
|
||||
mode: mode,
|
||||
target: "node",
|
||||
devtool: env === "development" ? "eval-source-map" : "source-map",
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false,
|
||||
},
|
||||
entry: {
|
||||
bw: entryPoint,
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".ts", ".js"],
|
||||
symlinks: false,
|
||||
modules: modulesPath,
|
||||
plugins: [new TsconfigPathsPlugin({ configFile: tsconfigPath })],
|
||||
},
|
||||
output: {
|
||||
filename: "[name].js",
|
||||
path: outputPath,
|
||||
clean: true,
|
||||
},
|
||||
module: { rules: getModuleRules() },
|
||||
plugins: getPlugins(env, envConfig, localesPath),
|
||||
externals: getExternals(externalsModulesDir),
|
||||
experiments: {
|
||||
asyncWebAssembly: true,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const getModuleRules = () => {
|
||||
return [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
use: "ts-loader",
|
||||
exclude: path.resolve(__dirname, "node_modules"),
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const getPlugins = (env, envConfig, localesPath) => {
|
||||
return [
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [{ from: localesPath, to: "locales" }],
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
"process.env.BWCLI_ENV": JSON.stringify(env),
|
||||
}),
|
||||
new webpack.BannerPlugin({
|
||||
banner: "#!/usr/bin/env node",
|
||||
raw: true,
|
||||
}),
|
||||
new webpack.IgnorePlugin({
|
||||
resourceRegExp: /^encoding$/,
|
||||
contextRegExp: /node-fetch/,
|
||||
}),
|
||||
new webpack.EnvironmentPlugin({
|
||||
ENV: env,
|
||||
BWCLI_ENV: env,
|
||||
FLAGS: envConfig.flags,
|
||||
DEV_FLAGS: envConfig.devFlags,
|
||||
}),
|
||||
new webpack.IgnorePlugin({
|
||||
resourceRegExp: /canvas/,
|
||||
contextRegExp: /jsdom$/,
|
||||
}),
|
||||
];
|
||||
};
|
||||
|
||||
const getExternals = (externalsModulesDir) => {
|
||||
return [
|
||||
nodeExternals({
|
||||
modulesDir: externalsModulesDir,
|
||||
allowlist: [/@bitwarden/],
|
||||
}),
|
||||
];
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getSharedConfig,
|
||||
getModuleRules,
|
||||
getPlugins,
|
||||
getExternals,
|
||||
};
|
||||
@@ -1,12 +1,46 @@
|
||||
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
|
||||
|
||||
// Re-use the OSS CLI webpack config
|
||||
const webpackConfig = require("../../apps/cli/webpack.config");
|
||||
module.exports = (webpackConfig, context) => {
|
||||
// Check if this is being called by Nx or directly by webpack CLI
|
||||
const isNxBuild = !!(context && context.options);
|
||||
|
||||
// Update paths to use the bit-cli entrypoint and tsconfig
|
||||
webpackConfig.entry = { bw: "../../bitwarden_license/bit-cli/src/bw.ts" };
|
||||
webpackConfig.resolve.plugins = [
|
||||
new TsconfigPathsPlugin({ configFile: "../../bitwarden_license/bit-cli/tsconfig.json" }),
|
||||
];
|
||||
let config;
|
||||
|
||||
module.exports = webpackConfig;
|
||||
if (isNxBuild) {
|
||||
// Use Nx configuration as base
|
||||
const nxConfig = require("../../apps/cli/webpack.nx.config.js");
|
||||
config = nxConfig(webpackConfig, context);
|
||||
|
||||
// Apply bit-cli specific modifications for Nx builds
|
||||
config.entry = { bw: context.options.main || "bitwarden_license/bit-cli/src/bw.ts" };
|
||||
config.resolve.plugins = [new TsconfigPathsPlugin({ configFile: "tsconfig.base.json" })];
|
||||
|
||||
// Update the locales path for bit-cli in Nx context
|
||||
const copyPlugin = config.plugins.find(
|
||||
(plugin) => plugin.constructor.name === "CopyWebpackPlugin",
|
||||
);
|
||||
if (copyPlugin) {
|
||||
copyPlugin.patterns = [{ from: "bitwarden_license/bit-cli/src/locales", to: "locales" }];
|
||||
}
|
||||
} else {
|
||||
// Use npm configuration as base
|
||||
const npmConfig = require("../../apps/cli/webpack.npm.config.js");
|
||||
config = { ...npmConfig };
|
||||
|
||||
// Apply bit-cli specific modifications for npm builds
|
||||
config.entry = { bw: "../../bitwarden_license/bit-cli/src/bw.ts" };
|
||||
config.resolve.plugins = [
|
||||
new TsconfigPathsPlugin({ configFile: "../../bitwarden_license/bit-cli/tsconfig.json" }),
|
||||
];
|
||||
|
||||
// Update the locales path for bit-cli (relative to bit-cli directory)
|
||||
const copyPlugin = config.plugins.find(
|
||||
(plugin) => plugin.constructor.name === "CopyWebpackPlugin",
|
||||
);
|
||||
if (copyPlugin) {
|
||||
copyPlugin.patterns = [{ from: "./src/locales", to: "locales" }];
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
9392
package-lock.json
generated
9392
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -170,6 +170,7 @@
|
||||
"@nx/eslint": "21.3.11",
|
||||
"@nx/jest": "21.3.11",
|
||||
"@nx/js": "21.3.11",
|
||||
"@nx/webpack": "21.3.11",
|
||||
"big-integer": "1.6.52",
|
||||
"braintree-web-drop-in": "1.44.0",
|
||||
"buffer": "6.0.3",
|
||||
|
||||
Reference in New Issue
Block a user