1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

build(desktop): integrate nx (#16860)

This commit is contained in:
Addison Beck
2025-10-14 06:27:38 -04:00
committed by GitHub
parent 0dd09caef7
commit 0538b587d4
4 changed files with 220 additions and 25 deletions

115
apps/desktop/project.json Normal file
View File

@@ -0,0 +1,115 @@
{
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"name": "desktop",
"projectType": "application",
"sourceRoot": "apps/desktop/src",
"tags": ["scope:desktop", "type:app"],
"targets": {
"build-native": {
"executor": "nx:run-commands",
"options": {
"command": "cd desktop_native && node build.js",
"cwd": "apps/desktop"
}
},
"build-main": {
"executor": "nx:run-commands",
"outputs": ["{workspaceRoot}/dist/apps/desktop"],
"options": {
"command": "cross-env NODE_ENV=production webpack --config webpack.config.js --config-name main",
"cwd": "apps/desktop"
},
"configurations": {
"development": {
"command": "cross-env NODE_ENV=development webpack --config webpack.config.js --config-name main"
},
"production": {
"command": "cross-env NODE_ENV=production webpack --config webpack.config.js --config-name main"
}
}
},
"build-preload": {
"executor": "nx:run-commands",
"outputs": ["{workspaceRoot}/dist/apps/desktop"],
"options": {
"command": "cross-env NODE_ENV=production webpack --config webpack.config.js --config-name preload",
"cwd": "apps/desktop"
},
"configurations": {
"development": {
"command": "cross-env NODE_ENV=development webpack --config webpack.config.js --config-name preload"
},
"production": {
"command": "cross-env NODE_ENV=production webpack --config webpack.config.js --config-name preload"
}
}
},
"build-renderer": {
"executor": "nx:run-commands",
"outputs": ["{workspaceRoot}/dist/apps/desktop"],
"options": {
"command": "cross-env NODE_ENV=production webpack --config webpack.config.js --config-name renderer",
"cwd": "apps/desktop"
},
"configurations": {
"development": {
"command": "cross-env NODE_ENV=development webpack --config webpack.config.js --config-name renderer"
},
"production": {
"command": "cross-env NODE_ENV=production webpack --config webpack.config.js --config-name renderer"
}
}
},
"build": {
"executor": "nx:run-commands",
"dependsOn": ["build-native"],
"outputs": ["{workspaceRoot}/dist/apps/desktop"],
"options": {
"parallel": true,
"commands": [
"nx run desktop:build-main",
"nx run desktop:build-preload",
"nx run desktop:build-renderer"
]
},
"configurations": {
"development": {
"commands": [
"nx run desktop:build-main --configuration=development",
"nx run desktop:build-preload --configuration=development",
"nx run desktop:build-renderer --configuration=development"
]
},
"production": {
"commands": [
"nx run desktop:build-main --configuration=production",
"nx run desktop:build-preload --configuration=production",
"nx run desktop:build-renderer --configuration=production"
]
}
}
},
"serve": {
"executor": "nx:run-commands",
"dependsOn": ["build-native"],
"options": {
"command": "node scripts/nx-serve.js",
"cwd": "apps/desktop"
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/apps/desktop"],
"options": {
"jestConfig": "apps/desktop/jest.config.js"
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/desktop/**/*.ts", "apps/desktop/**/*.html"]
}
}
}
}

View File

@@ -0,0 +1,42 @@
/* eslint-disable @typescript-eslint/no-require-imports */
const path = require("path");
const concurrently = require("concurrently");
const rimraf = require("rimraf");
const args = process.argv.splice(2);
const outputPath = path.resolve(__dirname, "../../../dist/apps/desktop");
rimraf.sync(outputPath);
require("fs").mkdirSync(outputPath, { recursive: true });
concurrently(
[
{
name: "Main",
command: `cross-env NODE_ENV=development OUTPUT_PATH=${outputPath} webpack --config webpack.config.js --config-name main --watch`,
prefixColor: "yellow",
},
{
name: "Prel",
command: `cross-env NODE_ENV=development OUTPUT_PATH=${outputPath} webpack --config webpack.config.js --config-name preload --watch`,
prefixColor: "magenta",
},
{
name: "Rend",
command: `cross-env NODE_ENV=development OUTPUT_PATH=${outputPath} webpack --config webpack.config.js --config-name renderer --watch`,
prefixColor: "cyan",
},
{
name: "Elec",
command: `npx wait-on ${outputPath}/main.js ${outputPath}/index.html && npx electron --no-sandbox --inspect=5858 ${args.join(
" ",
)} ${outputPath} --watch`,
prefixColor: "green",
},
],
{
prefix: "name",
outputStream: process.stdout,
killOthers: ["success", "failure"],
},
);

View File

@@ -8,7 +8,7 @@ const { AngularWebpackPlugin } = require("@ngtools/webpack");
const TerserPlugin = require("terser-webpack-plugin");
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
const { EnvironmentPlugin, DefinePlugin } = require("webpack");
const configurator = require("./config/config");
const configurator = require(path.resolve(__dirname, "config/config"));
module.exports.getEnv = function getEnv() {
const NODE_ENV = process.env.NODE_ENV == null ? "development" : process.env.NODE_ENV;
@@ -17,6 +17,14 @@ module.exports.getEnv = function getEnv() {
return { NODE_ENV, ENV };
};
const DEFAULT_PARAMS = {
outputPath: process.env.OUTPUT_PATH
? path.isAbsolute(process.env.OUTPUT_PATH)
? process.env.OUTPUT_PATH
: path.resolve(__dirname, process.env.OUTPUT_PATH)
: path.resolve(__dirname, "build"),
};
/**
* @param {{
* configName: string;
@@ -33,9 +41,11 @@ module.exports.getEnv = function getEnv() {
* entry: string;
* tsConfig: string;
* };
* outputPath?: string;
* }} params
*/
module.exports.buildConfig = function buildConfig(params) {
params = { ...DEFAULT_PARAMS, ...params };
const { NODE_ENV, ENV } = module.exports.getEnv();
console.log(`Building ${params.configName} Desktop App`);
@@ -47,13 +57,16 @@ module.exports.buildConfig = function buildConfig(params) {
resolve: {
extensions: [".tsx", ".ts", ".js"],
symlinks: false,
modules: [path.resolve("../../node_modules")],
modules: [
path.resolve(__dirname, "../../node_modules"),
path.resolve(process.cwd(), "node_modules"),
],
},
};
const getOutputConfig = (isDev) => ({
filename: "[name].js",
path: path.resolve(__dirname, "build"),
path: params.outputPath,
...(isDev && { devtoolModuleFilenameTemplate: "[absolute-resource-path]" }),
});
@@ -96,9 +109,9 @@ module.exports.buildConfig = function buildConfig(params) {
plugins: [
new CopyWebpackPlugin({
patterns: [
"./src/package.json",
{ from: "./src/images", to: "images" },
{ from: "./src/locales", to: "locales" },
path.resolve(__dirname, "src/package.json"),
{ from: path.resolve(__dirname, "src/images"), to: "images" },
{ from: path.resolve(__dirname, "src/locales"), to: "locales" },
],
}),
new DefinePlugin({
@@ -164,7 +177,7 @@ module.exports.buildConfig = function buildConfig(params) {
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "build"),
path: params.outputPath,
},
optimization: {
minimizer: [
@@ -200,7 +213,7 @@ module.exports.buildConfig = function buildConfig(params) {
{
loader: "babel-loader",
options: {
configFile: "../../babel.config.json",
configFile: path.resolve(__dirname, "../../babel.config.json"),
},
},
],
@@ -293,7 +306,7 @@ module.exports.buildConfig = function buildConfig(params) {
path.resolve(__dirname, "./src"),
),
new HtmlWebpackPlugin({
template: "./src/index.html",
template: path.resolve(__dirname, "src/index.html"),
filename: "index.html",
chunks: ["app/vendor", "app/main"],
}),

View File

@@ -1,18 +1,43 @@
const path = require("path");
const { buildConfig } = require("./webpack.base");
module.exports = buildConfig({
configName: "OSS",
renderer: {
entry: "./src/app/main.ts",
entryModule: "src/app/app.module#AppModule",
tsConfig: "./tsconfig.renderer.json",
},
main: {
entry: "./src/entry.ts",
tsConfig: "./tsconfig.json",
},
preload: {
entry: "./src/preload.ts",
tsConfig: "./tsconfig.json",
},
});
module.exports = (webpackConfig, context) => {
const isNxBuild = context && context.options;
if (isNxBuild) {
return buildConfig({
configName: "OSS",
renderer: {
entry: path.resolve(__dirname, "src/app/main.ts"),
entryModule: "src/app/app.module#AppModule",
tsConfig: path.resolve(context.context.root, "apps/desktop/tsconfig.renderer.json"),
},
main: {
entry: path.resolve(__dirname, "src/entry.ts"),
tsConfig: path.resolve(context.context.root, "apps/desktop/tsconfig.json"),
},
preload: {
entry: path.resolve(__dirname, "src/preload.ts"),
tsConfig: path.resolve(context.context.root, "apps/desktop/tsconfig.json"),
},
outputPath: path.resolve(context.context.root, context.options.outputPath),
});
} else {
return buildConfig({
configName: "OSS",
renderer: {
entry: path.resolve(__dirname, "src/app/main.ts"),
entryModule: "src/app/app.module#AppModule",
tsConfig: path.resolve(__dirname, "tsconfig.renderer.json"),
},
main: {
entry: path.resolve(__dirname, "src/entry.ts"),
tsConfig: path.resolve(__dirname, "tsconfig.json"),
},
preload: {
entry: path.resolve(__dirname, "src/preload.ts"),
tsConfig: path.resolve(__dirname, "tsconfig.json"),
},
});
}
};