Skip to content

Commit

Permalink
fix: ensure browser builds don't include any non-browser modules (#6743)
Browse files Browse the repository at this point in the history
currently we pull in BetterSqlite3Driver, SqliteDriver, and a few other
drivers & files that aren't possible to use in a browser context.
this change adds some more browser compatibility features so
webpack builds targeted at browsers will be able to complete

closes #6739
  • Loading branch information
imnotjames committed Sep 19, 2020
1 parent 5084e47 commit c714867
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 13 deletions.
19 changes: 15 additions & 4 deletions gulpfile.ts
Expand Up @@ -70,6 +70,15 @@ export class Gulpfile {
.pipe(gulp.dest("./build/browser/src"));
}

/**
* Replaces PlatformTools with browser-specific implementation called BrowserPlatformTools.
*/
@Task()
browserCopyDirectoryExportedClassesLoader() {
return gulp.src("./src/platform/BrowserDirectoryExportedClassesLoader.template")
.pipe(rename("BrowserDirectoryExportedClassesLoader.ts"))
.pipe(gulp.dest("./build/browser/src/platform"));
}
/**
* Replaces PlatformTools with browser-specific implementation called BrowserPlatformTools.
*/
Expand Down Expand Up @@ -97,7 +106,10 @@ export class Gulpfile {
"lib": ["es5", "es6", "dom"],
typescript: require("typescript")
});
const tsResult = gulp.src(["./build/browser/src/**/*.ts", "./node_modules/reflect-metadata/**/*.d.ts", "./node_modules/@types/**/*.ts"])
const tsResult = gulp.src([
"./build/browser/src/**/*.ts",
"./node_modules/reflect-metadata/**/*.d.ts"
])
.pipe(sourcemaps.init())
.pipe(tsProject());

Expand Down Expand Up @@ -151,8 +163,7 @@ export class Gulpfile {
typescript: require("typescript")
});
const tsResult = gulp.src([
"./src/**/*.ts",
"./node_modules/@types/**/*.ts",
"./src/**/*.ts"
])
.pipe(sourcemaps.init())
.pipe(tsProject());
Expand Down Expand Up @@ -231,7 +242,7 @@ export class Gulpfile {
package() {
return [
"clean",
["browserCopySources", "browserCopyPlatformTools", "browserCopyDisabledDriversDummy"],
["browserCopySources", "browserCopyPlatformTools", "browserCopyDisabledDriversDummy", "browserCopyDirectoryExportedClassesLoader"],
["packageCompile", "browserCompile"],
"packageMoveCompiledFiles",
[
Expand Down
5 changes: 5 additions & 0 deletions package.json
Expand Up @@ -11,6 +11,8 @@
},
"main": "./index.js",
"browser": {
"./browser/driver/aurora-data-api/AuroraDataApiDriver.js": "./browser/platform/BrowserDisabledDriversDummy.js",
"./browser/driver/cockroachdb/CockroachDriver.js": "./browser/platform/BrowserDisabledDriversDummy.js",
"./browser/driver/postgres/PostgresDriver.js": "./browser/platform/BrowserDisabledDriversDummy.js",
"./browser/driver/oracle/OracleDriver.ts": "./browser/platform/BrowserDisabledDriversDummy.js",
"./browser/driver/sap/SapDriver.ts": "./browser/platform/BrowserDisabledDriversDummy.js",
Expand All @@ -20,6 +22,9 @@
"./browser/driver/mongodb/MongoQueryRunner.js": "./browser/platform/BrowserDisabledDriversDummy.js",
"./browser/entity-manager/MongoEntityManager.js": "./browser/platform/BrowserDisabledDriversDummy.js",
"./browser/repository/MongoRepository.js": "./browser/platform/BrowserDisabledDriversDummy.js",
"./browser/driver/sqlite/SqliteDriver.js": "./browser/platform/BrowserDisabledDriversDummy.js",
"./browser/driver/better-sqlite3/BetterSqlite3Driver.js": "./browser/platform/BrowserDisabledDriversDummy.js",
"./browser/util/DirectoryExportedClassesLoader.js": "./browser/platform/BrowserDirectoryExportedClassesLoader.js",
"./index.js": "./browser/index.js"
},
"repository": {
Expand Down
5 changes: 2 additions & 3 deletions src/connection/ConnectionOptionsReader.ts
@@ -1,4 +1,3 @@
import dotenv from "dotenv";
import appRootPath from "app-root-path";
import {ConnectionOptions} from "./ConnectionOptions";
import {PlatformTools} from "../platform/PlatformTools";
Expand Down Expand Up @@ -95,9 +94,9 @@ export class ConnectionOptionsReader {

// if .env file found then load all its variables into process.env using dotenv package
if (foundFileFormat === "env") {
dotenv.config({ path: this.baseFilePath });
PlatformTools.dotenv(this.baseFilePath);
} else if (PlatformTools.fileExist(".env")) {
dotenv.config({ path: ".env" });
PlatformTools.dotenv(".env");
}

// Determine config file name
Expand Down
22 changes: 22 additions & 0 deletions src/platform/BrowserDirectoryExportedClassesLoader.template
@@ -0,0 +1,22 @@
/**
* Dummy functions for replacement via `package.json` in browser builds.
*
* If we don't include these functions typeorm will throw an error on runtime
* as well as during webpack builds.
*/

import {Logger} from "../logger/Logger";

/**
* Loads all exported classes from the given directory.
*/
export function importClassesFromDirectories(logger: Logger, directories: string[], formats = [".js", ".cjs", ".ts"]): Function[] {
return [];
}

/**
* Loads all json files from the given directory.
*/
export function importJsonsFromDirectories(directories: string[], format = ".json"): any[] {
return [];
}
28 changes: 26 additions & 2 deletions src/platform/BrowserDisabledDriversDummy.template
Expand Up @@ -3,8 +3,8 @@
* Using those classes reduces the build size by one third.
*
* If we don't include those dummy classes (and just disable the driver import
* with `false` in `package.json`) typeorm will throw an error on runtime,
* even if those driver are not used.
* with `false` in `package.json`) typeorm will throw an error on runtime and
* during webpack builds even if those driver are not used.
*/

/**
Expand Down Expand Up @@ -37,6 +37,18 @@ export class MongoRepository {}
*/
export class PostgresDriver {}

/**
* DO NOT IMPORT THIS CLASS -
* This is a dummy class for replacement via `package.json` in browser builds
*/
export class AuroraDataApiDriver {}

/**
* DO NOT IMPORT THIS CLASS -
* This is a dummy class for replacement via `package.json` in browser builds
*/
export class CockroachDriver {}

/**
* DO NOT IMPORT THIS CLASS -
* This is a dummy class for replacement via `package.json` in browser builds
Expand Down Expand Up @@ -66,3 +78,15 @@ export class MysqlDriver {}
* This is a dummy class for replacement via `package.json` in browser builds
*/
export class OracleDriver {}

/**
* DO NOT IMPORT THIS CLASS -
* This is a dummy class for replacement via `package.json` in browser builds
*/
export class SqliteDriver {}

/**
* DO NOT IMPORT THIS CLASS -
* This is a dummy class for replacement via `package.json` in browser builds
*/
export class BetterSqlite3Driver {}
13 changes: 9 additions & 4 deletions src/platform/BrowserPlatformTools.template
Expand Up @@ -75,6 +75,11 @@ export class PlatformTools {
return false;
}

static dotenv(pathStr: string): void {
if (this.type === "browser")
throw new Error(`This option/function is not supported in the browser environment. Failed operation: dotenv.config({ path: "${pathStr}" }).`);
}

/**
* Gets environment variable.
*/
Expand All @@ -89,7 +94,7 @@ export class PlatformTools {
throw new Error(`This option/function is not supported in the browser environment. Failed operation: fs.readFileSync("${filename}").`);
return null;
}

static appendFileSync(filename: string, data: any) {
if (this.type === "browser")
throw new Error(`This option/function is not supported in the browser environment. Failed operation: fs.appendFileSync("${filename}").`);
Expand Down Expand Up @@ -125,11 +130,11 @@ export class PlatformTools {
static logError(prefix: string, error: any) {
console.error(prefix + " ", error);
}

static logWarn(prefix: string, warning: any) {
console.warn(prefix + " ", warning);
}

static log(message: string) {
console.log(message);
}
Expand Down Expand Up @@ -165,4 +170,4 @@ if (typeof window !== "undefined") {
// NativeScript uses global, not window
if (typeof global !== "undefined") {
global.Buffer = require("buffer/").Buffer;
}
}
10 changes: 10 additions & 0 deletions src/platform/PlatformTools.ts
@@ -1,5 +1,6 @@
import * as path from "path";
import * as fs from "fs";
import dotenv from "dotenv";
import chalk from "chalk";
import {highlight, Theme} from "cli-highlight";

Expand Down Expand Up @@ -181,6 +182,15 @@ export class PlatformTools {
});
}

/**
* Loads a dotenv file into the environment variables.
*
* @param path The file to load as a dotenv configuration
*/
static dotenv(pathStr: string): void {
dotenv.config({ path: pathStr });
}

/**
* Gets environment variable.
*/
Expand Down

0 comments on commit c714867

Please sign in to comment.