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

Commit 19cf89f

Browse files
author
Dimitar Tachev
authored
Merge pull request #858 from NativeScript/tachev/terser
feat: replace UglifyJs with Terser
2 parents cbba16d + 167bc6e commit 19cf89f

10 files changed

+207
-115
lines changed

Diff for: demo/AngularApp/webpack.config.js

+63-34
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ const nsWebpack = require("nativescript-dev-webpack");
55
const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target");
66
const { nsReplaceBootstrap } = require("nativescript-dev-webpack/transformers/ns-replace-bootstrap");
77
const { nsReplaceLazyLoader } = require("nativescript-dev-webpack/transformers/ns-replace-lazy-loader");
8+
const { nsSupportHmrNg } = require("nativescript-dev-webpack/transformers/ns-support-hmr-ng");
89
const { getMainModulePath } = require("nativescript-dev-webpack/utils/ast-utils");
910
const CleanWebpackPlugin = require("clean-webpack-plugin");
1011
const CopyWebpackPlugin = require("copy-webpack-plugin");
1112
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
1213
const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin");
13-
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
14-
const { AngularCompilerPlugin } = require("@ngtools/webpack");
14+
const TerserPlugin = require("terser-webpack-plugin");
15+
const { getAngularCompilerPlugin } = require("nativescript-dev-webpack/plugins/NativeScriptAngularCompilerPlugin");
16+
const hashSalt = Date.now().toString();
1517

1618
module.exports = env => {
1719
// Add your custom Activities, Services and other Android app components here.
@@ -26,6 +28,7 @@ module.exports = env => {
2628
throw new Error("You need to provide a target platform!");
2729
}
2830

31+
const AngularCompilerPlugin = getAngularCompilerPlugin(platform);
2932
const projectRoot = __dirname;
3033

3134
// Default destination inside platforms/<platform>/...
@@ -45,29 +48,38 @@ module.exports = env => {
4548
uglify, // --env.uglify
4649
report, // --env.report
4750
sourceMap, // --env.sourceMap
51+
hiddenSourceMap, // --env.hiddenSourceMap
4852
hmr, // --env.hmr,
53+
unitTesting, // --env.unitTesting
4954
} = env;
50-
env.externals = env.externals || [];
51-
const externals = (env.externals).map((e) => { // --env.externals
52-
return new RegExp(e + ".*");
53-
});
5455

56+
const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap;
57+
const externals = nsWebpack.getConvertedExternals(env.externals);
5558
const appFullPath = resolve(projectRoot, appPath);
5659
const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
57-
58-
const entryModule = `${nsWebpack.getEntryModule(appFullPath)}.ts`;
60+
const tsConfigName = "tsconfig.tns.json";
61+
const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`;
5962
const entryPath = `.${sep}${entryModule}`;
63+
const entries = { bundle: entryPath, application: "./application.android" };
64+
if (platform === "ios") {
65+
entries["tns_modules/tns-core-modules/inspector_modules"] = "inspector_modules.js";
66+
};
67+
6068
const ngCompilerTransformers = [];
6169
const additionalLazyModuleResources = [];
6270
if (aot) {
6371
ngCompilerTransformers.push(nsReplaceBootstrap);
6472
}
6573

74+
if (hmr) {
75+
ngCompilerTransformers.push(nsSupportHmrNg);
76+
}
77+
6678
// when "@angular/core" is external, it's not included in the bundles. In this way, it will be used
6779
// directly from node_modules and the Angular modules loader won't be able to resolve the lazy routes
6880
// fixes https://github.com/NativeScript/nativescript-cli/issues/4024
69-
if (env.externals.indexOf("@angular/core") > -1) {
70-
const appModuleRelativePath = getMainModulePath(resolve(appFullPath, entryModule));
81+
if (env.externals && env.externals.indexOf("@angular/core") > -1) {
82+
const appModuleRelativePath = getMainModulePath(resolve(appFullPath, entryModule), tsConfigName);
7183
if (appModuleRelativePath) {
7284
const appModuleFolderPath = dirname(resolve(appFullPath, appModuleRelativePath));
7385
// include the lazy loader inside app module
@@ -79,14 +91,16 @@ module.exports = env => {
7991

8092
const ngCompilerPlugin = new AngularCompilerPlugin({
8193
hostReplacementPaths: nsWebpack.getResolver([platform, "tns"]),
82-
platformTransformers: ngCompilerTransformers.map(t => t(() => ngCompilerPlugin)),
83-
mainPath: resolve(appPath, entryModule),
84-
tsConfigPath: join(__dirname, "tsconfig.tns.json"),
94+
platformTransformers: ngCompilerTransformers.map(t => t(() => ngCompilerPlugin, resolve(appFullPath, entryModule))),
95+
mainPath: join(appFullPath, entryModule),
96+
tsConfigPath: join(__dirname, tsConfigName),
8597
skipCodeGeneration: !aot,
86-
sourceMap: !!sourceMap,
98+
sourceMap: !!isAnySourceMapEnabled,
8799
additionalLazyModuleResources: additionalLazyModuleResources
88100
});
89101

102+
let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist);
103+
90104
const config = {
91105
mode: uglify ? "production" : "development",
92106
context: appFullPath,
@@ -99,16 +113,15 @@ module.exports = env => {
99113
]
100114
},
101115
target: nativescriptTarget,
102-
entry: {
103-
bundle: entryPath,
104-
application: "./application.android",
105-
},
116+
entry: entries,
106117
output: {
107118
pathinfo: false,
108119
path: dist,
120+
sourceMapFilename,
109121
libraryTarget: "commonjs2",
110122
filename: "[name].js",
111123
globalObject: "global",
124+
hashSalt
112125
},
113126
resolve: {
114127
extensions: [".ts", ".js", ".scss", ".css"],
@@ -135,8 +148,9 @@ module.exports = env => {
135148
"fs": "empty",
136149
"__dirname": false,
137150
},
138-
devtool: sourceMap ? "inline-source-map" : "none",
151+
devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"),
139152
optimization: {
153+
runtimeChunk: "single",
140154
splitChunks: {
141155
cacheGroups: {
142156
vendor: {
@@ -153,12 +167,14 @@ module.exports = env => {
153167
},
154168
minimize: !!uglify,
155169
minimizer: [
156-
new UglifyJsPlugin({
170+
new TerserPlugin({
157171
parallel: true,
158172
cache: true,
159-
uglifyOptions: {
173+
sourceMap: isAnySourceMapEnabled,
174+
terserOptions: {
160175
output: {
161176
comments: false,
177+
semicolons: !isAnySourceMapEnabled
162178
},
163179
compress: {
164180
// The Android SBG has problems parsing the output
@@ -173,7 +189,7 @@ module.exports = env => {
173189
module: {
174190
rules: [
175191
{
176-
test: new RegExp(entryPath),
192+
test: nsWebpack.getEntryPathRegExp(appFullPath, entryPath),
177193
use: [
178194
// Require all Android app components
179195
platform === "android" && {
@@ -186,6 +202,9 @@ module.exports = env => {
186202
options: {
187203
angular: true,
188204
loadCss: !snapshot, // load the application css if in debug mode
205+
unitTesting,
206+
appFullPath,
207+
projectRoot,
189208
}
190209
},
191210
].filter(loader => !!loader)
@@ -239,25 +258,23 @@ module.exports = env => {
239258
}),
240259
// Remove all files from the out dir.
241260
new CleanWebpackPlugin([`${dist}/**/*`]),
242-
// Copy native app resources to out dir.
243-
new CopyWebpackPlugin([
244-
{
245-
from: `${appResourcesFullPath}/${appResourcesPlatformDir}`,
246-
to: `${dist}/App_Resources/${appResourcesPlatformDir}`,
247-
context: projectRoot
248-
},
249-
]),
250261
// Copy assets to out dir. Add your own globs as needed.
251262
new CopyWebpackPlugin([
252263
{ from: { glob: "fonts/**" } },
253264
{ from: { glob: "**/*.jpg" } },
254265
{ from: { glob: "**/*.png" } },
255266
], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
256267
// Generate a bundle starter script and activate it in package.json
257-
new nsWebpack.GenerateBundleStarterPlugin([
258-
"./vendor",
259-
"./bundle",
260-
]),
268+
new nsWebpack.GenerateBundleStarterPlugin(
269+
// Don't include `runtime.js` when creating a snapshot. The plugin
270+
// configures the WebPack runtime to be generated inside the snapshot
271+
// module and no `runtime.js` module exist.
272+
(snapshot ? [] : ["./runtime"])
273+
.concat([
274+
"./vendor",
275+
"./bundle",
276+
])
277+
),
261278
// For instructions on how to set up workers with webpack
262279
// check out https://github.com/nativescript/worker-loader
263280
new NativeScriptWorkerPlugin(),
@@ -267,6 +284,18 @@ module.exports = env => {
267284
],
268285
};
269286

287+
// Copy the native app resources to the out dir
288+
// only if doing a full build (tns run/build) and not previewing (tns preview)
289+
if (!externals || externals.length === 0) {
290+
config.plugins.push(new CopyWebpackPlugin([
291+
{
292+
from: `${appResourcesFullPath}/${appResourcesPlatformDir}`,
293+
to: `${dist}/App_Resources/${appResourcesPlatformDir}`,
294+
context: projectRoot
295+
},
296+
]));
297+
}
298+
270299

271300
if (report) {
272301
// Generate report files for bundles content

Diff for: demo/JavaScriptApp/webpack.config.js

+49-26
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ const CleanWebpackPlugin = require("clean-webpack-plugin");
77
const CopyWebpackPlugin = require("copy-webpack-plugin");
88
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
99
const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin");
10-
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
10+
const TerserPlugin = require("terser-webpack-plugin");
11+
const hashSalt = Date.now().toString();
1112

1213
module.exports = env => {
1314
// Add your custom Activities, Services and other android app components here.
1415
const appComponents = [
1516
"tns-core-modules/ui/frame",
1617
"tns-core-modules/ui/frame/activity",
17-
resolve(__dirname, "app/activity.android.js"),
18+
resolve(__dirname, "app/activity.android.js")
1819
];
1920

2021
const platform = env && (env.android && "android" || env.ios && "ios");
@@ -41,17 +42,24 @@ module.exports = env => {
4142
uglify, // --env.uglify
4243
report, // --env.report
4344
sourceMap, // --env.sourceMap
45+
hiddenSourceMap, // --env.hiddenSourceMap
4446
hmr, // --env.hmr,
47+
unitTesting, // --env.unitTesting
4548
} = env;
46-
const externals = (env.externals || []).map((e) => { // --env.externals
47-
return new RegExp(e + ".*");
48-
});
4949

50+
const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap;
51+
const externals = nsWebpack.getConvertedExternals(env.externals);
5052
const appFullPath = resolve(projectRoot, appPath);
5153
const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
5254

53-
const entryModule = nsWebpack.getEntryModule(appFullPath);
55+
const entryModule = nsWebpack.getEntryModule(appFullPath, platform);
5456
const entryPath = `.${sep}${entryModule}.js`;
57+
const entries = { bundle: entryPath, application: "./application.android" };
58+
if (platform === "ios") {
59+
entries["tns_modules/tns-core-modules/inspector_modules"] = "inspector_modules.js";
60+
};
61+
62+
let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist);
5563

5664
const config = {
5765
mode: uglify ? "production" : "development",
@@ -65,16 +73,15 @@ module.exports = env => {
6573
]
6674
},
6775
target: nativescriptTarget,
68-
entry: {
69-
bundle: entryPath,
70-
application: "./application.android",
71-
},
76+
entry: entries,
7277
output: {
7378
pathinfo: false,
7479
path: dist,
80+
sourceMapFilename,
7581
libraryTarget: "commonjs2",
7682
filename: "[name].js",
7783
globalObject: "global",
84+
hashSalt
7885
},
7986
resolve: {
8087
extensions: [".js", ".scss", ".css"],
@@ -101,8 +108,9 @@ module.exports = env => {
101108
"fs": "empty",
102109
"__dirname": false,
103110
},
104-
devtool: sourceMap ? "inline-source-map" : "none",
111+
devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"),
105112
optimization: {
113+
runtimeChunk: "single",
106114
splitChunks: {
107115
cacheGroups: {
108116
vendor: {
@@ -120,12 +128,14 @@ module.exports = env => {
120128
},
121129
minimize: !!uglify,
122130
minimizer: [
123-
new UglifyJsPlugin({
131+
new TerserPlugin({
124132
parallel: true,
125133
cache: true,
126-
uglifyOptions: {
134+
sourceMap: isAnySourceMapEnabled,
135+
terserOptions: {
127136
output: {
128137
comments: false,
138+
semicolons: !isAnySourceMapEnabled
129139
},
130140
compress: {
131141
// The Android SBG has problems parsing the output
@@ -140,7 +150,7 @@ module.exports = env => {
140150
module: {
141151
rules: [
142152
{
143-
test: new RegExp(entryPath),
153+
test: nsWebpack.getEntryPathRegExp(appFullPath, entryPath),
144154
use: [
145155
// Require all Android app components
146156
platform === "android" && {
@@ -152,6 +162,9 @@ module.exports = env => {
152162
loader: "nativescript-dev-webpack/bundle-config-loader",
153163
options: {
154164
loadCss: !snapshot, // load the application css if in debug mode
165+
unitTesting,
166+
appFullPath,
167+
projectRoot,
155168
}
156169
},
157170
].filter(loader => !!loader)
@@ -196,25 +209,23 @@ module.exports = env => {
196209
}),
197210
// Remove all files from the out dir.
198211
new CleanWebpackPlugin([`${dist}/**/*`]),
199-
// Copy native app resources to out dir.
200-
new CopyWebpackPlugin([
201-
{
202-
from: `${appResourcesFullPath}/${appResourcesPlatformDir}`,
203-
to: `${dist}/App_Resources/${appResourcesPlatformDir}`,
204-
context: projectRoot
205-
},
206-
]),
207212
// Copy assets to out dir. Add your own globs as needed.
208213
new CopyWebpackPlugin([
209214
{ from: { glob: "fonts/**" } },
210215
{ from: { glob: "**/*.jpg" } },
211216
{ from: { glob: "**/*.png" } },
212217
], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
213218
// Generate a bundle starter script and activate it in package.json
214-
new nsWebpack.GenerateBundleStarterPlugin([
215-
"./vendor",
216-
"./bundle",
217-
]),
219+
new nsWebpack.GenerateBundleStarterPlugin(
220+
// Don't include `runtime.js` when creating a snapshot. The plugin
221+
// configures the WebPack runtime to be generated inside the snapshot
222+
// module and no `runtime.js` module exist.
223+
(snapshot ? [] : ["./runtime"])
224+
.concat([
225+
"./vendor",
226+
"./bundle",
227+
])
228+
),
218229
// For instructions on how to set up workers with webpack
219230
// check out https://github.com/nativescript/worker-loader
220231
new NativeScriptWorkerPlugin(),
@@ -227,6 +238,18 @@ module.exports = env => {
227238
],
228239
};
229240

241+
// Copy the native app resources to the out dir
242+
// only if doing a full build (tns run/build) and not previewing (tns preview)
243+
if (!externals || externals.length === 0) {
244+
config.plugins.push(new CopyWebpackPlugin([
245+
{
246+
from: `${appResourcesFullPath}/${appResourcesPlatformDir}`,
247+
to: `${dist}/App_Resources/${appResourcesPlatformDir}`,
248+
context: projectRoot
249+
},
250+
]));
251+
}
252+
230253
if (report) {
231254
// Generate report files for bundles content
232255
config.plugins.push(new BundleAnalyzerPlugin({

0 commit comments

Comments
 (0)