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

Commit 4756198

Browse files
authored
refactor: generate webpack.common templates on prepublish (#150)
* refactor: move templates to separate dir * refactor: generate webpack.common templates on prepublish * fix(ns-bundle): pass platform and uglify as env properties * fix(ns-bundle): don't readd scripts from nativescript-dev-webpack * fix(ns-bundle): use webpack.config.js instead of webpack.common.js BREAKING: The ns-bundle script will now target the `webpack.config.js` file in your repository instead of the `webpack.common.js` one. If you changed your configuration, you need to apply them to `webpack.config.js` or replace the whole file with your correct configuration. The following files are no longer needed and can be safely removed from the project: `webpack.common.js`, `webpack.android.js`, `webpack.ios.js`.
1 parent 0fd9159 commit 4756198

31 files changed

+841
-438
lines changed

Diff for: bin/ns-bundle

+14-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
#!/usr/bin/env node
22

3-
const spawn = require("child_process").spawn;
4-
const resolve = require("path").resolve;
3+
const { spawn } = require("child_process");
4+
const { resolve: pathResolve } = require("path");
5+
const { getPackageJson } = require("../projectHelpers");
56

6-
const getPackageJson = require("../projectHelpers").getPackageJson;
7-
8-
const PROJECT_DIR = resolve(__dirname, "../../../");
7+
const PROJECT_DIR = pathResolve(__dirname, "../../../");
98
const packageJson = getPackageJson(PROJECT_DIR);
109

1110
if (!process.env.npm_config_argv) {
@@ -67,7 +66,16 @@ function webpack(platform) {
6766
return new Promise(function (resolve, reject) {
6867
console.log(`Running webpack for ${platform}...`);
6968

70-
spawnChildProcess(true, "webpack", `--config=webpack.${platform}.js`, "--progress")
69+
const args = [
70+
true, // show output on console
71+
`webpack`,
72+
`--config=webpack.config.js`,
73+
`--progress`,
74+
`--env.${platform}`,
75+
process.env.npm_config_uglify && `--env.uglify`,
76+
];
77+
78+
spawnChildProcess(...args)
7179
.then(resolve)
7280
.catch(throwError);
7381
});

Diff for: npmScriptsManager.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const DEPRECATED_SCRIPT_TEMPLATES = Object.freeze([
1717
const PLATFORMS = Object.freeze(["android", "ios"]);
1818

1919
function addNpmScripts(scripts) {
20+
scripts = scripts || {};
21+
2022
Object.keys(SCRIPT_TEMPLATES).forEach(name => {
2123
packageJson = addPlatformScript(scripts, name, SCRIPT_TEMPLATES[name]);
2224
});
@@ -51,8 +53,8 @@ function addPlatformScript(scripts, nameTemplate, commandTemplate) {
5153
}
5254

5355
function removePlatformScripts(scripts, nameTemplate) {
54-
if (!scripts) {
55-
return;
56+
if (!scripts || Object.keys(SCRIPT_TEMPLATES).includes(nameTemplate)) {
57+
return scripts;
5658
}
5759

5860
PLATFORMS.forEach(function (platform) {

Diff for: package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"url": "https://github.com/NativeScript/nativescript-dev-webpack.git"
1515
},
1616
"scripts": {
17-
"postinstall": "node postinstall.js"
17+
"postinstall": "node postinstall.js",
18+
"prepublishOnly": "node ./templates/buildTemplates.js"
1819
},
1920
"bin": {
2021
"install-ns-webpack": "./bin/install-ns-webpack",

Diff for: projectFilesManager.js

+7-9
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ function addProjectFiles(projectDir, appDir) {
77
const projectTemplates = getProjectTemplates(projectDir);
88
Object.keys(projectTemplates).forEach(function(templateName) {
99
const templateDestination = projectTemplates[templateName];
10-
templateName = path.resolve(templateName)
10+
templateName = path.resolve(templateName);
1111
copyTemplate(templateName, templateDestination);
1212
});
1313

@@ -43,24 +43,22 @@ function copyTemplate(templateName, destinationPath) {
4343
// Create destination file, only if not present.
4444
if (!fs.existsSync(destinationPath)) {
4545
console.info(`Creating file: ${destinationPath}`);
46+
console.log(templateName)
4647
const content = fs.readFileSync(templateName, "utf8");
4748
fs.writeFileSync(destinationPath, content);
4849
}
4950
}
5051

5152
function getProjectTemplates(projectDir) {
52-
let templates = {
53-
"webpack.android.js.template": "webpack.android.js",
54-
"webpack.ios.js.template": "webpack.ios.js",
55-
};
53+
let templates = {}
5654

5755
if (helpers.isAngular({projectDir})) {
58-
templates["webpack.common.js.angular.template"] = "webpack.common.js";
56+
templates["webpack.config.js.ng.template"] = "webpack.config.js";
5957
templates["tsconfig.aot.json.template"] = "tsconfig.aot.json";
6058
} else if (helpers.isTypeScript({projectDir})) {
61-
templates["webpack.common.js.typescript.template"] = "webpack.common.js";
59+
templates["webpack.config.js.ts.template"] = "webpack.config.js";
6260
} else {
63-
templates["webpack.common.js.javascript.template"] = "webpack.common.js";
61+
templates["webpack.config.js.js.template"] = "webpack.config.js";
6462
}
6563

6664
return getFullTemplatesPath(projectDir, templates);
@@ -85,7 +83,7 @@ function getFullTemplatesPath(projectDir, templates) {
8583
let updatedTemplates = {};
8684

8785
Object.keys(templates).forEach(key => {
88-
const updatedKey = getFullPath(__dirname, key);
86+
const updatedKey = getFullPath(path.join(__dirname, "templates"), key);
8987
const updatedValue = getFullPath(projectDir, templates[key])
9088

9189
updatedTemplates[updatedKey] = updatedValue;

Diff for: templates/buildTemplates.js

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const { writeFileSync } = require("fs");
2+
3+
saveTemplate("js");
4+
saveTemplate("ts");
5+
saveTemplate("ng");
6+
7+
function saveTemplate(target) {
8+
const content = buildTemplate(target);
9+
writeFileSync(`./templates/webpack.config.js.${target}.template`, content);
10+
}
11+
12+
function buildTemplate(target) {
13+
let template = "";
14+
15+
template += getResource(target, "imports");
16+
template += getResource(target, "exports");
17+
template += getResource(target, "getPlatform");
18+
19+
const rules = getResource(target, "rules");
20+
template += rulesBuilder(rules);
21+
22+
const plugins = getResource(target, "plugins");
23+
template += pluginsBuilder(plugins);
24+
25+
template += require(`./${target}/getExtensions`);
26+
27+
return template;
28+
};
29+
30+
function getResource(target, resourceName) {
31+
const common = require(`./common/${resourceName}`);
32+
const maybeSpecific = tryRequire(`./${target}/${resourceName}`);
33+
34+
return merge(resourceName, common, maybeSpecific);
35+
}
36+
37+
function tryRequire(path) {
38+
try {
39+
return require(path);
40+
} catch(e) { }
41+
}
42+
43+
function merge(resource, common, specific) {
44+
const allResources = specific ? `${common}\n${specific}\n` : `${common}\n`;
45+
return isArray(resource) ? `[${allResources} ]` : allResources;
46+
}
47+
48+
function isArray(resource) {
49+
return ["rules", "plugins"].includes(resource);
50+
}
51+
52+
function pluginsBuilder(plugins) {
53+
const uglify = require("./common/uglify");
54+
return `function getPlugins(platform, env) {
55+
let plugins = ${plugins};
56+
${uglify}
57+
58+
return plugins;
59+
}\n`;
60+
}
61+
62+
function rulesBuilder(rules) {
63+
return `function getRules() {
64+
return ${rules};
65+
}\n\n`;
66+
}

Diff for: templates/common/exports.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
module.exports = `
2+
const mainSheet = \`app.css\`;
3+
4+
module.exports = env => {
5+
const platform = getPlatform(env);
6+
7+
// Default destination inside platforms/<platform>/...
8+
const path = resolve(nsWebpack.getAppPath(platform));
9+
10+
const entry = {
11+
// Discover entry module from package.json
12+
bundle: \`./\${nsWebpack.getEntryModule()}\`,
13+
14+
// Vendor entry with third-party libraries
15+
vendor: \`./vendor\`,
16+
17+
// Entry for stylesheet with global application styles
18+
[mainSheet]: \`./\${mainSheet}\`,
19+
};
20+
21+
const rules = getRules();
22+
const plugins = getPlugins(platform, env);
23+
const extensions = getExtensions(platform);
24+
25+
return {
26+
context: resolve("./app"),
27+
target: nativescriptTarget,
28+
entry,
29+
output: {
30+
pathinfo: true,
31+
path,
32+
libraryTarget: "commonjs2",
33+
filename: "[name].js",
34+
},
35+
resolve: {
36+
extensions,
37+
38+
// Resolve {N} system modules from tns-core-modules
39+
modules: [
40+
"node_modules/tns-core-modules",
41+
"node_modules",
42+
]
43+
},
44+
node: {
45+
// Disable node shims that conflict with NativeScript
46+
"http": false,
47+
"timers": false,
48+
"setImmediate": false,
49+
"fs": "empty",
50+
},
51+
module: { rules },
52+
plugins,
53+
};
54+
};
55+
`;
56+

Diff for: templates/common/getPlatform.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = `
2+
function getPlatform(env) {
3+
return env.android ? "android" :
4+
env.ios ? "ios" :
5+
() => { throw new Error("You need to provide a target platform!") };
6+
}
7+
`;
8+

Diff for: templates/common/imports.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = `const { resolve, join } = require("path");
2+
3+
const webpack = require("webpack");
4+
const nsWebpack = require("nativescript-dev-webpack");
5+
const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target");
6+
const CopyWebpackPlugin = require("copy-webpack-plugin");
7+
const ExtractTextPlugin = require("extract-text-webpack-plugin");
8+
`;

Diff for: templates/common/plugins.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module.exports = `
2+
new ExtractTextPlugin(mainSheet),
3+
4+
// Vendor libs go to the vendor.js chunk
5+
new webpack.optimize.CommonsChunkPlugin({
6+
name: ["vendor"],
7+
}),
8+
9+
// Define useful constants like TNS_WEBPACK
10+
new webpack.DefinePlugin({
11+
"global.TNS_WEBPACK": "true",
12+
}),
13+
14+
// Copy assets to out dir. Add your own globs as needed.
15+
new CopyWebpackPlugin([
16+
{ from: mainSheet },
17+
{ from: "css/**" },
18+
{ from: "fonts/**" },
19+
{ from: "**/*.jpg" },
20+
{ from: "**/*.png" },
21+
{ from: "**/*.xml" },
22+
], { ignore: ["App_Resources/**"] }),
23+
24+
// Generate a bundle starter script and activate it in package.json
25+
new nsWebpack.GenerateBundleStarterPlugin([
26+
"./vendor",
27+
"./bundle",
28+
]),`;

Diff for: templates/common/rules.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module.exports = `
2+
{
3+
test: /\\.html$|\\.xml$/,
4+
use: [
5+
"raw-loader",
6+
]
7+
},
8+
// Root stylesheet gets extracted with bundled dependencies
9+
{
10+
test: new RegExp(mainSheet),
11+
use: ExtractTextPlugin.extract([
12+
{
13+
loader: "resolve-url-loader",
14+
options: { silent: true },
15+
},
16+
"nativescript-css-loader",
17+
"nativescript-dev-webpack/platform-css-loader",
18+
]),
19+
},
20+
// Other CSS files get bundled using the raw loader
21+
{
22+
test: /\\.css$/,
23+
exclude: new RegExp(mainSheet),
24+
use: [
25+
"raw-loader",
26+
]
27+
},
28+
// SASS support
29+
{
30+
test: /\\.scss$/,
31+
use: [
32+
"raw-loader",
33+
"resolve-url-loader",
34+
"sass-loader",
35+
]
36+
},
37+
`;

Diff for: templates/common/uglify.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = `
2+
if (env.uglify) {
3+
plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true }));
4+
5+
// Work around an Android issue by setting compress = false
6+
const compress = platform !== "android";
7+
plugins.push(new webpack.optimize.UglifyJsPlugin({
8+
mangle: { except: nsWebpack.uglifyMangleExcludes },
9+
compress,
10+
}));
11+
}`;

Diff for: templates/js/getExtensions.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = `
2+
// Resolve platform-specific modules like module.android.js
3+
function getExtensions(platform) {
4+
return Object.freeze([
5+
\`.\${platform}.js\`,
6+
\`.\${platform}.css\`,
7+
".js",
8+
".css",
9+
]);
10+
}
11+
`;

Diff for: templates/ng/getExtensions.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = `
2+
// Resolve platform-specific modules like module.android.js
3+
function getExtensions(platform) {
4+
return Object.freeze([
5+
\`.\${platform}.ts\`,
6+
\`.\${platform}.js\`,
7+
\`.\${platform}.css\`,
8+
".aot.ts",
9+
".ts",
10+
".js",
11+
".css",
12+
]);
13+
}
14+
`;

Diff for: templates/ng/imports.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = `const { AotPlugin } = require("@ngtools/webpack");`;

Diff for: templates/ng/plugins.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = `
2+
// Angular AOT compiler
3+
new AotPlugin({
4+
tsConfigPath: "tsconfig.aot.json",
5+
entryModule: resolve(__dirname, "app/app.module#AppModule"),
6+
typeChecking: false
7+
}),
8+
9+
// Resolve .ios.css and .android.css component stylesheets
10+
new nsWebpack.StyleUrlResolvePlugin({platform}),
11+
`;

Diff for: templates/ng/rules.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = `
2+
// Compile TypeScript files with ahead-of-time compiler.
3+
{
4+
test: /\\.ts$/,
5+
loaders: [
6+
"nativescript-dev-webpack/tns-aot-loader",
7+
"@ngtools/webpack",
8+
]
9+
}
10+
`;

Diff for: templates/ts/getExtensions.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = `
2+
// Resolve platform-specific modules like module.android.js
3+
function getExtensions(platform) {
4+
return Object.freeze([
5+
\`.\${platform}.ts\`,
6+
\`.\${platform}.js\`,
7+
\`.\${platform}.css\`,
8+
".ts",
9+
".js",
10+
".css",
11+
]);
12+
}
13+
`;

0 commit comments

Comments
 (0)