Skip to content
This repository was archived by the owner on Aug 7, 2021. It is now read-only.

refactor: remove building through npm scripts #336

Merged
merged 3 commits into from
Dec 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ A package to help with webpacking NativeScript apps.

```sh
$ npm install --save-dev nativescript-dev-webpack
$ npm install

$ npm run start-android-bundle
$ tns run android --bundle
or
$ npm run start-ios-bundle
$ tns run ios --bundle
```

# Documentation
Expand Down
249 changes: 2 additions & 247 deletions bin/ns-bundle
Original file line number Diff line number Diff line change
@@ -1,249 +1,4 @@
#!/usr/bin/env node

const { spawn } = require("child_process");
const { resolve: pathResolve, join } = require("path");
const { existsSync } = require("fs");

const semver = require("semver");

const { getPackageJson, getProjectDir } = require("../projectHelpers");

const PROJECT_DIR = getProjectDir({ nestingLvl: 2 });
const packageJson = getPackageJson(PROJECT_DIR);

if (!process.env.npm_config_argv) {
throwError({message: "No flags provided."});
}

const escapeWithQuotes = arg => `"${arg}"`;
const isTnsCommand = flag => flag.endsWith("-app");
const isEnvCommand = flag => flag.indexOf("env.") > -1;
const shouldUglify = () => process.env.npm_config_uglify;

const platformSupportsSnapshot = platform => platform === "android";
const osSupportsSnapshot = () => require("os").type() != "Windows_NT";
const snapshotOption = env =>
process.env.npm_config_snapshot || (env && env.includes("env.snapshot"));

const shouldSnapshot = (platform, env) =>
platformSupportsSnapshot(platform) &&
osSupportsSnapshot() &&
snapshotOption(env);

const npmArgs = JSON.parse(process.env.npm_config_argv).original;
const tnsArgs = getTnsArgs(npmArgs);
const flags = npmArgs.filter(a => a.startsWith("--")).map(a => a.substring(2));
const options = getOptions(flags);

function getTnsArgs(args) {
const other = [
"run",
"ns-bundle",
"--android",
"--ios",
"--uglify",
"--snapshot",
"--nobundle",
];

return args.filter(a => !other.includes(a) && !isTnsCommand(a) && !isEnvCommand(a));
}

execute(options);

function execute(options) {
const platform = options.platform;
let commands = [
() => runTns("prepare", platform)
];

if (options.bundle) {
commands = [
...commands,
() => cleanApp(platform),
() => cleanSnapshotArtefacts(),
() => cleanBuildArtefacts(platform),
() => webpack(platform, options.env),
];
}

if (shouldSnapshot(platform, options.env)) {
commands.push(() => installSnapshotArtefacts());
}

// If "build-app" or "start-app" is specified,
// the respective command should be run last.
if (options.command) {
commands.push(() => runTns(options.command, platform));
}
return commands.reduce((current, next) => current.then(next), Promise.resolve());
}

function cleanBuildArtefacts(platform) {
return new Promise((resolve, reject) => {
if (platform !== "android") {
return resolve();
}

getTnsVersion().then(version => {
// the android build artefacts should be cleaned manually
// for nativescript-cli v3.0.1 and below or if using uglify

if (!semver.gte(version, "3.0.1") || shouldUglify()) {
gradlewClean().then(resolve).catch(throwError);
} else {
return resolve();
}
}).catch(throwError);
});
}

function cleanSnapshotArtefacts() {
require("../snapshot/android/project-snapshot-generator").cleanSnapshotArtefacts(PROJECT_DIR);
}

function installSnapshotArtefacts() {
require("../snapshot/android/project-snapshot-generator").installSnapshotArtefacts(PROJECT_DIR);
}

function gradlewClean() {
return new Promise((resolve, reject) => {
const platformsPath = join(PROJECT_DIR, "platforms", "android")
const gradlew = pathResolve(platformsPath, "gradlew");
if (!existsSync(gradlew)) {
return resolve();
}

spawnChildProcess(gradlew, "-p", platformsPath, "clean")
.then(resolve)
.catch(throwError);
});
}

function getTnsVersion() {
return new Promise((resolve, reject) => {
const childProcess = spawn("tns", ["--version"], { shell: true });
let stdoutData = "";
childProcess.stdout.on("data", data => stdoutData += data);

childProcess.on("close", code => {
if (code) {
reject({
code,
message: `child process exited with code ${code}`,
});
} else {
const versionRegex = /^(?:\d+\.){2}\d+.*?$/m;
const matches = stdoutData.toString().match(versionRegex);
const version = matches && matches[0] && matches[0].trim();
resolve(version);
}
});
});
}

// Clear platform/**/app folder contents
function cleanApp(platform) {
return new Promise((resolve, reject) => {

spawnChildProcess("tns", "clean-app", platform)
.then(resolve)
.catch(throwError)
});
}

function webpack(platform, env) {
return new Promise(function (resolve, reject) {
console.log(`Running webpack for ${platform}...`);

const args = [
`node`,
`--preserve-symlinks`,
`./node_modules/.bin/webpack`,
`--config=webpack.config.js`,
`--progress`,
`--env.${platform}`,
...env.map(item => `--${item}`),
shouldUglify() && `--env.uglify`,
shouldSnapshot(platform) && `--env.snapshot`
].filter(a => !!a);

spawnChildProcess(...args)
.then(resolve)
.catch(throwError);
});
}

function runTns(command, platform) {
return new Promise((resolve, reject) => {
console.log(`Running tns ${command}...`);

spawnChildProcess("tns", command, platform, "--bundle", "--disable-npm-install", ...tnsArgs)
.then(resolve)
.catch(throwError);
});
}

function getOptions(flags) {
return {
platform: getPlatform(flags),
command: getCommand(flags),
env: flags.filter(isEnvCommand),
bundle: !flags.includes("nobundle"),
};
}


function getPlatform(flags) {
if (flags.includes("android") && flags.includes("ios")) {
throwError({message: "You cannot use both --android and --ios flags!"});
}

if (flags.includes("android")) {
return "android";
} else if (flags.includes("ios")) {
return "ios";
} else {
throwError({message:
"You must provide a target platform! " +
"Use either --android, or --ios flag."});
}
}

function getCommand(flags) {
const commands = flags.filter(isTnsCommand);
if (commands.length > 1) {
throwError({message: `You can't use ${commands.join(", ")} together!`});
}

return commands.length && commands[0].replace(/-app/, "");
}

function spawnChildProcess(command, ...args) {
return new Promise((resolve, reject) => {
const escapedArgs = args.map(escapeWithQuotes)

const childProcess = spawn(command, escapedArgs, {
stdio: "inherit",
cwd: PROJECT_DIR,
shell: true,
});

childProcess.on("close", code => {
if (code === 0) {
resolve();
} else {
reject({
code,
message: `child process exited with code ${code}`,
});
}
});
});
}

function throwError(error) {
console.error(error.message);
process.exit(error.code || 1);
}

console.error("Using npm run scripts is no longer supported. Use CLI commands and pass the --bundle flag instead.\nExample:\ntns build android --bundle")
process.exit(1);
16 changes: 8 additions & 8 deletions dependencyManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ If you want to force update them, please run "node_modules/.bin/update-ns-webpac

const USAGE_MESSAGE = `
NativeScript Webpack plugin was successfully added.
You can now bundle your project with the following npm scripts:
- "npm run build-android-bundle" to build for android.
- "npm run build-ios-bundle" to build for ios.
- "npm run start-android-bundle" to run on android.
- "npm run start-ios-bundle" to run on ios.
You can also pass the "--uglify" flag to use UglifyJS for minification.
You can now bundle your project by passing --bundle flag to NativeScript CLI commands:
- tns build android --bundle
- tns build ios --bundle
- tns run android --bundle
- tns run ios --bundle
You can also pass the "--env.uglify" flag to use UglifyJS for minification.
For more information check out https://docs.nativescript.org/tooling/bundling-with-webpack#bundling.
`;

Expand Down Expand Up @@ -103,14 +103,14 @@ function resolveAngularDeps(usedDependencies) {
});
}

return depsToAdd;
return depsToAdd;
}

function getVersionWithoutPatch(fullVersion) {
if (!fullVersion) {
return "";
}

const prereleaseVersions = Object.freeze(["next", "latest", "rc"]);
if (prereleaseVersions.includes(fullVersion)) {
return fullVersion;
Expand Down