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

Commit 21d6807

Browse files
authored
Merge pull request #39 from NativeScript/ExcludeUnusedElements
ExcludeUnusedElements plugin + loader added
2 parents b89c568 + 7b5e9ac commit 21d6807

File tree

4 files changed

+96
-11
lines changed

4 files changed

+96
-11
lines changed

Diff for: index.js

+44-9
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ if (isAngular) {
1717

1818
//HACK: changes the JSONP chunk eval function to `global["nativescriptJsonp"]`
1919
// applied to tns-java-classes.js only
20-
exports.NativeScriptJsonpPlugin = function(options) {
20+
exports.NativeScriptJsonpPlugin = function (options) {
2121
};
2222

2323
exports.NativeScriptJsonpPlugin.prototype.apply = function (compiler) {
@@ -40,7 +40,42 @@ exports.NativeScriptJsonpPlugin.prototype.apply = function (compiler) {
4040
});
4141
};
4242

43-
exports.GenerateBundleStarterPlugin = function(bundles) {
43+
exports.ExcludeUnusedElementsPlugin = function () {
44+
};
45+
46+
exports.ExcludeUnusedElementsPlugin.prototype.apply = function (compiler) {
47+
compiler.plugin("normal-module-factory", function (nmf) {
48+
nmf.plugin("before-resolve", function (result, callback) {
49+
if (!result) {
50+
return callback();
51+
}
52+
53+
if (result.request === "globals" || result.request === "ui/core/view") {
54+
return callback(null, result);
55+
}
56+
57+
if (result.context.indexOf("tns-core-modules") === -1) {
58+
if (result.contextInfo.issuer &&
59+
result.contextInfo.issuer.indexOf("element-registry") !== -1 && global["ELEMENT_REGISTRY"] &&
60+
!global["ELEMENT_REGISTRY"][result.request]) {
61+
return callback();
62+
63+
} else {
64+
return callback(null, result);
65+
}
66+
}
67+
68+
if (result.contextInfo.issuer.indexOf("bundle-entry-points") !== -1 && global["ELEMENT_REGISTRY"] &&
69+
!global["ELEMENT_REGISTRY"][result.request]) {
70+
return callback();
71+
}
72+
73+
return callback(null, result);
74+
});
75+
});
76+
};
77+
78+
exports.GenerateBundleStarterPlugin = function (bundles) {
4479
this.bundles = bundles;
4580
};
4681

@@ -58,22 +93,22 @@ exports.GenerateBundleStarterPlugin.prototype = {
5893
cb();
5994
});
6095
},
61-
generatePackageJson: function() {
96+
generatePackageJson: function () {
6297
var packageJsonPath = path.join(this.webpackContext, "package.json");
6398
var packageData = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
6499
packageData.main = "starter";
65100

66101
return new sources.RawSource(JSON.stringify(packageData, null, 4));
67102
},
68-
generateStarterModule: function() {
69-
var moduleSource = this.bundles.map(function(bundle) {
103+
generateStarterModule: function () {
104+
var moduleSource = this.bundles.map(function (bundle) {
70105
return "require(\"" + bundle + "\");";
71106
}).join("\n");
72107
return new sources.RawSource(moduleSource);
73108
},
74109
};
75110

76-
exports.getEntryModule = function() {
111+
exports.getEntryModule = function () {
77112
const maybePackageJsonEntry = getPackageJsonEntry();
78113
if (!maybePackageJsonEntry) {
79114
throw new Error("app/package.json must contain a `main` attribute.");
@@ -83,12 +118,12 @@ exports.getEntryModule = function() {
83118
return maybeAotEntry || maybePackageJsonEntry;
84119
};
85120

86-
exports.getAppPath = function(platform) {
121+
exports.getAppPath = function (platform) {
87122
var projectDir = path.dirname(path.dirname(__dirname));
88123

89124
if (/ios/i.test(platform)) {
90125
var appName = path.basename(projectDir);
91-
var sanitizedName = appName.split("").filter(function(c) {
126+
var sanitizedName = appName.split("").filter(function (c) {
92127
return /[a-zA-Z0-9]/.test(c);
93128
}).join("");
94129
return "platforms/ios/" + sanitizedName + "/app";
@@ -127,7 +162,7 @@ function getPackageJsonEntry() {
127162
const entry = packageJsonSource.main;
128163

129164
return entry ? entry.replace(/\.js$/i, "") : null;
130-
}
165+
}
131166

132167
function getAppPackageJsonSource() {
133168
const projectDir = getProjectDir();

Diff for: postinstall.js

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ configureDevDependencies(packageJson, function (add) {
5656
add("@angular/compiler-cli", "2.3.1");
5757
add("@ngtools/webpack", "1.2.1");
5858
add("typescript", "~2.0.10");
59+
add("htmlparser2", "^3.9.2");
5960
} else {
6061
add("awesome-typescript-loader", "~3.0.0-beta.9");
6162
}

Diff for: tns-xml-loader.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
var htmlparser = require("htmlparser2");
2+
3+
var UI_PATH = "ui/";
4+
5+
var MODULES = {
6+
"TabViewItem": "ui/tab-view",
7+
"FormattedString": "text/formatted-string",
8+
"Span": "text/span",
9+
"ActionItem": "ui/action-bar",
10+
"NavigationButton": "ui/action-bar",
11+
"SegmentedBarItem": "ui/segmented-bar",
12+
};
13+
14+
var ELEMENT_REGISTRY = "ELEMENT_REGISTRY";
15+
16+
if (!global[ELEMENT_REGISTRY]) {
17+
global[ELEMENT_REGISTRY] = {};
18+
}
19+
20+
module.exports = function (source, map) {
21+
this.cacheable();
22+
23+
var loader = this;
24+
25+
var parser = new htmlparser.Parser({
26+
onopentag: function (name, attribs) {
27+
// kebab-case to CamelCase
28+
var elementName = name.split("-").map(function (s) { return s[0].toUpperCase() + s.substring(1); }).join("");
29+
// Module path from element name
30+
var modulePath = MODULES[elementName] || UI_PATH +
31+
(elementName.toLowerCase().indexOf("layout") !== -1 ? "layouts/" : "") +
32+
elementName.split(/(?=[A-Z])/).join("-").toLowerCase();
33+
// Update ELEMENT_REGISTRY
34+
global[ELEMENT_REGISTRY][modulePath] = elementName;
35+
}
36+
}, { decodeEntities: true, lowerCaseTags: false });
37+
parser.write(source);
38+
parser.end();
39+
40+
this.callback(null, source, map);
41+
};

Diff for: webpack.common.js.angular.template

+10-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ module.exports = function (platform, destinationApp) {
4545
"./vendor",
4646
"./bundle",
4747
]),
48+
49+
// Exclude explicitly required but never declared in XML elements.
50+
// Loader nativescript-dev-webpack/tns-xml-loader should be added for *.xml/html files.
51+
new nsWebpack.ExcludeUnusedElementsPlugin(),
52+
4853
//Angular AOT compiler
4954
new AotPlugin({
5055
tsConfigPath: "tsconfig.aot.json",
@@ -101,8 +106,11 @@ module.exports = function (platform, destinationApp) {
101106
module: {
102107
loaders: [
103108
{
104-
test: /\.html$/,
105-
loader: "raw-loader"
109+
test: /\.html$|\.xml$/,
110+
loaders: [
111+
"raw-loader",
112+
'nativescript-dev-webpack/tns-xml-loader'
113+
]
106114
},
107115
// Root app.css file gets extracted with bundled dependencies
108116
{

0 commit comments

Comments
 (0)