UNPKG

@rnv/engine-rn-windows

Version:

ReNative Engine to build for Windows platform with react native support.

386 lines 20.7 kB
"use strict"; 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