@rnv/engine-rn-windows
Version:
ReNative Engine to build for Windows platform with react native support.
386 lines • 20.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.signWindowsApp = exports.installWindowsApp = exports.packageWindowsApp = exports.clearWindowsTemporaryFiles = exports.packageBundleForWindows = exports.configureWindowsProject = exports.ruWindowsProject = void 0;
var tslib_1 = require("tslib");
var fs_1 = tslib_1.__importStar(require("fs"));
var glob_1 = tslib_1.__importDefault(require("glob"));
var path_1 = tslib_1.__importDefault(require("path"));
var core_1 = require("@rnv/core");
// import cli from '@react-native-windows/cli';
// import runWindowsCMD from '@react-native-windows/cli/lib-commonjs/runWindows/runWindows';
// import msBuildTools from '@react-native-windows/cli/lib-commonjs/runWindows/utils/msbuildtools';
// import info from '@react-native-windows/cli/lib-commonjs/runWindows/utils/info';
var copyTemplate_1 = require("./copyTemplate");
var getContext_1 = require("../getContext");
// TODO Is there a way to convert these requires into proper imports
// eslint-disable-next-line global-require
var cli = require('@react-native-windows/cli');
// eslint-disable-next-line global-require
var runWindows = require('@react-native-windows/cli/lib-commonjs/runWindows/runWindows').runWindowsCommand.func;
// const msBuildTools = require(
// '@react-native-windows/cli/lib-commonjs/runWindows/utils/msbuildtools'
// ).default;
var runPowerShellScriptFunction = require('@react-native-windows/cli/lib-commonjs/runWindows/utils/commandWithProgress').runPowerShellScriptFunction;
var env = process === null || process === void 0 ? void 0 : process.env;
var defaultOptions = {
language: 'cpp',
experimentalNuGetDependency: false,
useWinUI3: false,
nuGetTestVersion: null,
reactNativeEngine: 'chakra',
nuGetTestFeed: null,
overwrite: false,
release: false,
root: undefined,
arch: 'x86',
singleproc: true,
emulator: undefined,
device: undefined,
target: undefined,
remoteDebugging: undefined,
logging: false,
packager: true,
bundle: false,
launch: true,
autolink: false,
build: true,
deploy: true,
sln: undefined,
proj: undefined,
appPath: undefined,
msbuildprops: undefined,
buildLogDirectory: undefined,
info: false,
directDebugging: undefined,
telemetry: true,
devPort: undefined,
additionalMetroOptions: {},
packageExtension: 'appx',
};
var getOptions = function (c, injectedOptions) {
if (injectedOptions === void 0) { injectedOptions = {}; }
var language = (0, getContext_1.getConfigProp)('language') || defaultOptions.language;
var release = (0, getContext_1.getConfigProp)('release') || defaultOptions.release;
var root = (0, getContext_1.getConfigProp)('root') || c.paths.project.dir;
var arch = (0, getContext_1.getConfigProp)('arch') || defaultOptions.arch;
var singleproc = (0, getContext_1.getConfigProp)('singleproc') || defaultOptions.singleproc;
var emulator = (0, getContext_1.getConfigProp)('emulator') || defaultOptions.emulator;
var device = (0, getContext_1.getConfigProp)('device') || defaultOptions.device;
var target = (0, getContext_1.getConfigProp)('target') || defaultOptions.target;
var overwrite = (0, getContext_1.getConfigProp)('overwrite') || defaultOptions.overwrite;
var remoteDebugging = (0, getContext_1.getConfigProp)('remoteDebugging') || defaultOptions.remoteDebugging;
var logging = (0, getContext_1.getConfigProp)('logging') || defaultOptions.logging;
var packager = (0, getContext_1.getConfigProp)('packager') || defaultOptions.packager;
var bundle = (0, getContext_1.getConfigProp)('bundle') || defaultOptions.bundle;
var launch = (0, getContext_1.getConfigProp)('launch') || defaultOptions.launch;
var autolink = (0, getContext_1.getConfigProp)('autolink') || defaultOptions.autolink;
var build = (0, getContext_1.getConfigProp)('build') || defaultOptions.build;
var deploy = (0, getContext_1.getConfigProp)('deploy') || defaultOptions.deploy;
var sln = (0, getContext_1.getConfigProp)('sln') || defaultOptions.sln;
var proj = (0, getContext_1.getConfigProp)('proj') || c.paths.project.dir;
var appPath = (0, getContext_1.getConfigProp)('appPath') || (0, core_1.getAppFolder)();
var msbuildprops = (0, getContext_1.getConfigProp)('msbuildprops') || defaultOptions.msbuildprops;
var buildLogDirectory = (0, getContext_1.getConfigProp)('buildLogDirectory') || path_1.default.join((0, core_1.getAppFolder)(), 'BuildLogs');
var info = (0, getContext_1.getConfigProp)('info') || defaultOptions.info;
var directDebugging = (0, getContext_1.getConfigProp)('directDebugging') || defaultOptions.directDebugging;
var telemetry = (0, getContext_1.getConfigProp)('telemetry') || defaultOptions.telemetry;
var devPort = (0, getContext_1.getConfigProp)('devPort') || c.runtime.port;
var env = (0, getContext_1.getConfigProp)('environment');
// Aditional ReNative property configurations
var bundleAssets = (0, getContext_1.getConfigProp)('bundleAssets') === true;
var bundleIsDev = (0, getContext_1.getConfigProp)('bundleIsDev') === true;
var additionalMetroOptions = (0, getContext_1.getConfigProp)('additionalMetroOptions') || defaultOptions.additionalMetroOptions;
// TODO Default options, need to configure this via renative.json
var options = tslib_1.__assign({ release: release, root: root, arch: arch, singleproc: singleproc, emulator: emulator, device: device, target: target, remoteDebugging: remoteDebugging, logging: logging, packager: packager, bundle: bundle, launch: launch, autolink: autolink, build: build, deploy: deploy, sln: sln, proj: proj, appPath: appPath, msbuildprops: msbuildprops, buildLogDirectory: buildLogDirectory, info: info, directDebugging: directDebugging, telemetry: telemetry, devPort: devPort, language: language, overwrite: overwrite, bundleAssets: bundleAssets, bundleIsDev: bundleIsDev,
// Additional values passed to react native cli start function call
additionalMetroOptions: tslib_1.__assign(tslib_1.__assign({}, additionalMetroOptions), {
// ENV variables must not be removed as metro will fail without them
env: tslib_1.__assign(tslib_1.__assign({ NODE_ENV: env || 'development' }, core_1.CoreEnvVars.BASE()), core_1.CoreEnvVars.RNV_EXTENSIONS()) }) }, injectedOptions);
return options;
};
// TODO Document/comment each of the functions
var ruWindowsProject = function (injectedOptions) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var c, options, args, cnfg, projectConfig, config;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
(0, core_1.logDefault)('runWindowsProject');
c = (0, core_1.getContext)();
options = getOptions(c, injectedOptions);
args = [];
if (!options.additionalMetroOptions.env.RNV_APP_BUILD_DIR) {
(0, core_1.logWarning)('Enviroment variables not injected properly! Running metro will return an error!');
}
cnfg = {
sourceDir: (0, core_1.getAppFolder)(true),
solutionFile: "".concat(c.runtime.appId, ".sln"),
project: {
projectName: c.runtime.appId,
projectFile: "".concat(c.runtime.appId, "\\").concat(c.runtime.appId, ".vcxproj"),
projectLang: options.language,
// TODO Validate if this is ok
projectGuid: c.runtime.appId,
},
folder: c.paths.project.dir,
};
projectConfig = {
windows: cnfg,
};
config = {
root: c.paths.project.dir,
commands: cli.commands,
platforms: {
windows: {
linkConfig: function () { return null; },
projectConfig: function () {
return cli.projectConfig(c.paths.project.dir, {
project: projectConfig,
});
},
dependencyConfig: cli.dependencyConfig,
npmPackageName: 'react-native-windows',
},
},
project: projectConfig,
};
// This needs to be set before the first run to make sure there is just
// one build process running and the run command does not hang if you use
// it with -r flag
return [4 /*yield*/, setSingleBuildProcessForWindows(c)];
case 1:
// This needs to be set before the first run to make sure there is just
// one build process running and the run command does not hang if you use
// it with -r flag
_a.sent();
if (!(options.bundleAssets || options.release)) return [3 /*break*/, 3];
(0, core_1.logDebug)('Assets will be bundled');
return [4 /*yield*/, packageBundleForWindows(options.bundleIsDev)];
case 2:
_a.sent();
_a.label = 3;
case 3: return [4 /*yield*/, runWindows(args, config, options)];
case 4:
_a.sent();
return [2 /*return*/, true];
}
});
}); };
exports.ruWindowsProject = ruWindowsProject;
var copyWindowsTemplateProject = function (injectedOptions) {
if (injectedOptions === void 0) { injectedOptions = {}; }
return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var c, options, opts;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
c = (0, core_1.getContext)();
options = getOptions(c, injectedOptions);
opts = tslib_1.__assign(tslib_1.__assign({}, options), injectedOptions);
return [4 /*yield*/, (0, copyTemplate_1.copyProjectTemplateAndReplace)(c, opts)];
case 1:
_a.sent();
if (!fs_1.default.existsSync(opts.buildLogDirectory)) {
fs_1.default.mkdirSync(opts.buildLogDirectory, { recursive: true });
}
return [2 /*return*/, true];
}
});
});
};
exports.configureWindowsProject = copyWindowsTemplateProject;
function clearWindowsTemporaryFiles() {
var c = (0, core_1.getContext)();
(0, core_1.logDefault)('clearWindowsTemporaryFiles');
var logging = (0, getContext_1.getConfigProp)('logging') || defaultOptions.logging;
var opts = {
cwd: c.paths.project.dir,
detached: false,
stdio: logging ? 'inherit' : 'ignore',
};
// TODO This should be part of rnv clean and rnv run -r and not part of the SDK
// This should resolve as it used internally by react-native-windows
// eslint-disable-next-line global-require
var child_process_1 = require('child_process');
// NuGet cache
child_process_1.spawn('cmd.exe', ['/C', 'dotnet nuget locals all --clear'], opts);
// NPM cache
delete process.env.NPM_CONFIG_CACHE;
delete process.env.NPM_CONFIG_PREFIX;
// TODO Arbitrary 3s delay before continuing to make sure all files were removed is not ideal
// But without it bundler executes at the same time deletion occurs and therefore bundler
// fails to initiate
return new Promise(function (resolve) { return setTimeout(function () { return resolve(true); }, 4000); });
}
exports.clearWindowsTemporaryFiles = clearWindowsTemporaryFiles;
var packageBundleForWindows = function (isDev) {
if (isDev === void 0) { isDev = false; }
var c = (0, core_1.getContext)();
(0, core_1.logDefault)('packageBundleForWindows');
// const { maxErrorLength } = c.program.opts();
var entryFile = (0, getContext_1.getConfigProp)('entryFile');
if (!c.runtime.appId)
return;
var args = [
'bundle',
'--platform',
'windows',
'--dev',
isDev,
'--assets-dest',
"".concat((0, core_1.getAppFolder)().replace(/\//g, '\\'), "\\").concat(c.runtime.appId, "\\Bundle"),
'--entry-file',
"".concat(entryFile, ".js"),
'--bundle-output',
"".concat((0, core_1.getAppFolder)().replace(/\//g, '\\'), "\\").concat(c.runtime.appId, "\\Bundle\\index.windows.bundle"),
];
if (c.program.opts().info) {
args.push('--verbose');
}
if ((0, getContext_1.getConfigProp)('enableSourceMaps')) {
// Directory might not exist yet (created during builds proccess)
var dir = path_1.default.join((0, core_1.getAppFolder)(), 'Release', c.runtime.appId, 'sourcemaps', 'react');
if (!fs_1.default.existsSync(dir)) {
fs_1.default.mkdirSync(dir, { recursive: true });
}
args.push('--sourcemap-output');
args.push("".concat(dir, "\\index.windows.bundle.map"));
}
return (0, core_1.executeAsync)("node ".concat((0, core_1.doResolve)('react-native', true, { forceForwardPaths: false }), "\\local-cli\\cli.js ").concat(args.join(' '), " --config=metro.config.js"), { env: tslib_1.__assign(tslib_1.__assign({}, core_1.CoreEnvVars.BASE()), core_1.CoreEnvVars.RNV_EXTENSIONS()) });
};
exports.packageBundleForWindows = packageBundleForWindows;
var setSingleBuildProcessForWindows = function (c) {
(0, core_1.logDefault)('setSingleBuildProcessForWindows');
// eslint-disable-next-line eqeqeq
if (env.MSBUILDDISABLENODEREUSE != 1) {
var logging = (0, getContext_1.getConfigProp)('logging') || defaultOptions.logging;
var opts = {
cwd: c.paths.project.dir,
detached: false,
stdio: logging ? 'inherit' : 'ignore',
};
// TODO This should be part of rnv clean and rnv run -r and not part of the SDK
// This should resolve as it used internally by react-native-windows
// eslint-disable-next-line global-require
var child_process_1 = require('child_process');
child_process_1.spawn('cmd.exe', ['/C', 'set MSBUILDDISABLENODEREUSE=1'], opts);
}
};
// Copied from @react-native-windows/cli/overrides/lib-commonjs/runWindows/utils/deploy.js
var pushd = function (pathArg) {
var cwd = process.cwd();
process.chdir(pathArg);
return function () { return process.chdir(cwd); };
};
// Copied from @react-native-windows/cli/overrides/lib-commonjs/runWindows/utils/deploy.js
var getWindowsStoreAppUtils = function (c) {
var appFolder = (0, core_1.getAppFolder)();
var RNWinPath = path_1.default.join(path_1.default.dirname(require.resolve('@react-native-windows/cli/package.json', {
paths: [c.paths.project.dir],
})));
(0, core_1.logWarning)("RN Win Path: ".concat(RNWinPath));
var popd = pushd(appFolder);
var windowsStoreAppUtilsPath = path_1.default.join(RNWinPath, 'powershell', 'WindowsStoreAppUtils.ps1');
// This should resolve as it used internally by react-native-windows
// eslint-disable-next-line global-require
var child_process_1 = require('child_process');
child_process_1.execSync("powershell -NoProfile Unblock-File \"".concat(windowsStoreAppUtilsPath, "\""));
popd();
return windowsStoreAppUtilsPath;
};
function getAppPackage(c, injectedOptions) {
var options = getOptions(c, injectedOptions);
var appFolder = (0, core_1.getAppFolder)();
var appPackage;
var rootGlob = "".concat(appFolder.replace(/\\/g, '/'), "/{*/AppPackages,AppPackages/*}");
var newGlob = "".concat(rootGlob, "/*_").concat(options.arch === 'x86' ? '{Win32,x86}' : options.arch, "_Test");
var result = glob_1.default.sync(newGlob);
if (result.length > 1 && c.runtime.appId) {
var newFilteredGlobs = result.filter(function (x) { return x.includes(c.runtime.appId || ''); });
if (newFilteredGlobs.length >= 1) {
(0, core_1.logWarning)("More than one app package found: ".concat(result));
}
appPackage = newFilteredGlobs[0];
}
else if (result.length === 1) {
appPackage = result[0];
}
if (!appPackage) {
throw new Error("Unable to find app package using search path: \"".concat(appPackage, "\""));
}
return appPackage;
}
var signWindowsApp = function (c, script, windowsStoreAppUtils) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var logging, err_1;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
logging = (0, getContext_1.getConfigProp)('logging') || defaultOptions.logging;
// TODO Installs the app instead of just saving a certificate
return [4 /*yield*/, runPowerShellScriptFunction('Saving certificate in the local certificate store', windowsStoreAppUtils, "Install-App \"".concat(script, "\" -Force"), logging)];
case 1:
// TODO Installs the app instead of just saving a certificate
_a.sent();
return [3 /*break*/, 3];
case 2:
err_1 = _a.sent();
(0, core_1.logError)(err_1);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
}); };
exports.signWindowsApp = signWindowsApp;
var installWindowsApp = function (c, script, windowsStoreAppUtils) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var logging;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
logging = (0, getContext_1.getConfigProp)('logging') || defaultOptions.logging;
return [4 /*yield*/, runPowerShellScriptFunction('Removing old version of the app', windowsStoreAppUtils, "Uninstall-App ".concat(c.runtime.appId), logging)];
case 1:
_a.sent();
return [4 /*yield*/, runPowerShellScriptFunction('Installing new version of the app', windowsStoreAppUtils, "Install-App \"".concat(script, "\" -Force"), logging)];
case 2:
_a.sent();
return [2 /*return*/];
}
});
}); };
exports.installWindowsApp = installWindowsApp;
var packageWindowsApp = function (injectedOptions) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var c, appFolder, windowsStoreAppUtils, appPackage, RNWinPowershellPath, script, e_1;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
c = (0, core_1.getContext)();
if (!c.runtime.appId)
return [2 /*return*/];
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
appFolder = (0, core_1.getAppFolder)();
windowsStoreAppUtils = getWindowsStoreAppUtils(c);
appPackage = getAppPackage(c, injectedOptions);
RNWinPowershellPath = path_1.default.join(path_1.default.dirname(require.resolve('@react-native-windows/cli/package.json', {
paths: [c.paths.project.dir],
})), 'powershell');
// TODO Sign-AppDevPackage cannot be executed
(0, fs_1.copyFileSync)(path_1.default.join(RNWinPowershellPath, 'Sign-AppDevPackage.ps1'), path_1.default.join(appFolder, 'AppPackages', c.runtime.appId, "".concat(c.runtime.appId, "_1.0.0.0_Win32_Test")));
script = glob_1.default.sync(path_1.default.join(c.paths.project.dir, appPackage, 'Add-AppDevPackage.ps1'))[0];
// await signWindowsApp(c, script, windowsStoreAppUtils);
return [4 /*yield*/, installWindowsApp(c, script, windowsStoreAppUtils)];
case 2:
// await signWindowsApp(c, script, windowsStoreAppUtils);
_a.sent();
return [3 /*break*/, 4];
case 3:
e_1 = _a.sent();
(0, core_1.logError)("App packaging failed with error: ".concat(e_1));
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
}); };
exports.packageWindowsApp = packageWindowsApp;
//# sourceMappingURL=index.js.map