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

feat(scripts): add ns-bundle and verify-bundle #69

Merged
merged 3 commits into from
Feb 8, 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
1 change: 1 addition & 0 deletions bin/install-ns-webpack
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
var installer = require("../installer");

installer.addProjectFiles();
installer.removeDeprecatedNpmScripts();
installer.addNpmScripts();
installer.addProjectDependencies();
108 changes: 108 additions & 0 deletions bin/ns-bundle
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#!/usr/bin/env node

const spawn = require("child_process").spawn;
const path = require("path");

const PROJECT_DIR = path.resolve(__dirname, "../../../");

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

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

execute(options);

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

if (options.bundle) {
commands.unshift(() => webpack(options.platform));
}

return commands.reduce((current, next) => current.then(next), Promise.resolve());
}

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

spawnChildProcess("tns", "clean-app", platform)
.then(() => spawnChildProcess("webpack", `--config=webpack.${platform}.js`, "--progress"))
.then(resolve)
.catch(throwError);
});
}

function runTns(command, platform) {
console.log(`Running tns ${command}...`);
return new Promise((resolve, reject) => {
spawnChildProcess("tns", command, platform, "--bundle", "--disable-npm-install")
.then(resolve)
.catch(throwError);
});
}

function getOptions(flags) {
let options = {};
options.platform = getPlatform(flags);
options.command = getCommand(flags);
options.bundle = !flags.includes("nobundle");

return options;
}

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) {
if (flags.includes("start-app") && flags.includes("build-app")) {
throwError({message: "You cannot use both --start-app and --build-app flags!"});
}

if (flags.includes("start-app")) {
return "run";
} else if (flags.includes("build-app")) {
return "build";
} else {
throwError({message: "You must provide either --start-app, or --build-app flag!"});
}
}

function spawnChildProcess(command, ...args) {
return new Promise((resolve, reject) => {
const childProcess = spawn(command, args, { stdio: "inherit", pwd: PROJECT_DIR });

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);
}

1 change: 1 addition & 0 deletions bin/ns-bundle.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@node %~dp0\ns-bundle %*
101 changes: 101 additions & 0 deletions bin/ns-verify-bundle
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env node

const path = require("path");
const fs = require("fs");

const PROJECT_DIR = path.resolve(__dirname, "../../../");
console.log(PROJECT_DIR);
const APP_ID = require(path.resolve(PROJECT_DIR, "./package.json")).nativescript.id;
const APP_NAME = APP_ID.substring(APP_ID.lastIndexOf(".") + 1);
const PROJECT_PATHS = {
android: path.resolve(PROJECT_DIR, "platforms/android/src/main/assets/app"),
ios: path.resolve(PROJECT_DIR, `platforms/ios/build/emulator/${APP_NAME}.app/app`),
};

const npmArgs = JSON.parse(process.env.npm_config_argv).original;
const flags = npmArgs.filter(a => a.startsWith("--")).map(a => a.substring(2));
const file = getTargetFile(flags);
const platform = getPlatform(flags);

const filePath = path.resolve(PROJECT_PATHS[platform], file);

console.log(`Checking ${filePath} exists`);
if (!fs.existsSync(filePath)) {
throwError({message: `${filePath} doesn not exist!`});
}

const maxSize = getMaxSize(flags);
if (maxSize) {
checkFileSizeIsUnder(filePath, maxSize).then().catch(throwError);
}

function getTargetFile(flags) {
let fileFlags = flags.filter(f => f.startsWith("file="));

if (fileFlags.length != 1) {
throwError({message: "You must provide a target file!"});
}

fileFlags = fileFlags[0];
return fileFlags.substring(fileFlags.indexOf("=") + 1);
}

function getMaxSize(flags) {
let sizeFlags = flags.filter(f => f.startsWith("maxSize="));

if (sizeFlags.length == 0) {
return;
} else if (sizeFlags.length > 1) {
throwError({message: "You must provide 0 or 1 maxSize flags!"});
}

sizeFlags = sizeFlags[0];
return sizeFlags.substring(sizeFlags.indexOf("=") + 1);
}

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 checkFileSizeIsUnder(fileName, sizeInBytes) {
console.log(`Checking ${fileName} size is under ${sizeInBytes}`);

return new Promise((resolve, reject) => {
readFile(fileName)
.then(content => {
if (content.length <= sizeInBytes) {
resolve();
} else {
reject({message: `File "${fileName}" exceeded file size of "${sizeInBytes}".`});
}
});
});
}

function readFile(fileName) {
return new Promise((resolve, reject) => {
fs.readFile(fileName, "utf-8", (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}

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

1 change: 1 addition & 0 deletions bin/ns-verify-bundle.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@node %~dp0\ns-verify-bundle %*
1 change: 1 addition & 0 deletions bin/remove-ns-webpack
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
var installer = require("../installer");

installer.removeProjectFiles();
installer.removeDeprecatedNpmScripts();
installer.removeNpmScripts();
installer.removeProjectDependencies();
34 changes: 24 additions & 10 deletions installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,24 @@ exports.removeProjectFiles = removeProjectFiles;

function getScriptTemplates() {
return {
"clean-[PLATFORM]": "tns clean-app [PLATFORM]",
"prewebpack-[PLATFORM]": "npm run clean-[PLATFORM]",
"webpack-[PLATFORM]": "webpack --config=webpack.[PLATFORM].js --progress",
"prestart-[PLATFORM]-bundle": "npm run webpack-[PLATFORM]",
"start-[PLATFORM]-bundle": "tns run [PLATFORM] --bundle --disable-npm-install",
"prebuild-[PLATFORM]-bundle": "npm run webpack-[PLATFORM]",
"build-[PLATFORM]-bundle": "tns build [PLATFORM] --bundle --disable-npm-install",
"ns-bundle": "ns-bundle",
"start-[PLATFORM]-bundle": "npm run ns-bundle --[PLATFORM] --start-app",
"build-[PLATFORM]-bundle": "npm run ns-bundle --[PLATFORM] --build-app",
};
}

function getDeprecatedScriptTemplates() {
return [
"clean-[PLATFORM]",
"prewebpack-[PLATFORM]",
"webpack-[PLATFORM]",
"prestart-[PLATFORM]-bundle",
"start-[PLATFORM]-bundle",
"prebuild-[PLATFORM]-bundle",
"build-[PLATFORM]-bundle",
]
}

function addNpmScripts() {
var scriptTemplates = getScriptTemplates();
Object.keys(scriptTemplates).forEach(function(templateName) {
Expand All @@ -96,9 +104,15 @@ function addNpmScripts() {
}
exports.addNpmScripts = addNpmScripts;

function removeNpmScripts() {
var scriptTemplates = getScriptTemplates();
Object.keys(scriptTemplates).forEach(function(templateName) {
function removeDeprecatedNpmScripts() {
removeNpmScripts(getDeprecatedScriptTemplates());
}

exports.removeDeprecatedNpmScripts = removeDeprecatedNpmScripts;

function removeNpmScripts(scriptTemplates) {
var scriptTemplates = scriptTemplates || Object.keys(getScriptTemplates());
scriptTemplates.forEach(function(templateName) {
removePlatformScripts(packageJson, templateName);
});
}
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
},
"bin": {
"install-ns-webpack": "./bin/install-ns-webpack",
"remove-ns-webpack": "./bin/remove-ns-webpack"
"remove-ns-webpack": "./bin/remove-ns-webpack",
"ns-bundle": "./bin/ns-bundle",
"ns-verify-bundle": "./bin/ns-verify-bundle"
},
"dependencies": {},
"devDependencies": {}
Expand Down
1 change: 1 addition & 0 deletions postinstall.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var installer = require("./installer");

installer.addProjectFiles();
installer.removeDeprecatedNpmScripts();
installer.addNpmScripts();
installer.addProjectDependencies();
5 changes: 4 additions & 1 deletion tns-xml-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ function getTemplateSource(path, source) {
return source;
} else if (isComponent(path)) {
const templateMatcher = /template\s*:\s*([`'"])((.|\n)*?)\1/;
return templateMatcher.test(source) ? source.replace(templateMatcher, "$2") : "";
let match = templateMatcher.exec(source);

return match ? match[2] : "";

} else {
throw new Error(`The NativeScript XML loader must be used with HTML, XML or TypeScript files`);
}
Expand Down
2 changes: 1 addition & 1 deletion webpack.common.js.angular.template
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ module.exports = function (platform, destinationApp) {
{
test: /\.ts$/,
loaders: [
"nativescript-dev-webpack/tns-xml-loader",
"nativescript-dev-webpack/tns-aot-loader",
"@ngtools/webpack",
"nativescript-dev-webpack/tns-xml-loader",
]
},
// SASS support
Expand Down