diff --git a/.vscode/launch.json b/.vscode/launch.json index 3cd1efa9..5c1dca3e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,8 @@ "program": "${workspaceFolder}/node_modules/jasmine/bin/jasmine.js", "args": [ "--config=jasmine-config/jasmine.json" - ] + ], + "preLaunchTask": "npm:tsc" }, { "type": "node", diff --git a/CHANGELOG.md b/CHANGELOG.md index 3336338e..56bd54c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ + +## [1.0.2](https://github.com/NativeScript/nativescript-dev-webpack/compare/1.0.1...1.0.2) (2019-07-26) + + +### Bug Fixes + +* do not require `.js.map` files in the entry points when someone is using devtool: "source-map" ([#968](https://github.com/NativeScript/nativescript-dev-webpack/issues/968)) ([4bb6124](https://github.com/NativeScript/nativescript-dev-webpack/commit/4bb6124)) +* avoid getting invalid require calls when building from Windows ([#989](https://github.com/NativeScript/nativescript-dev-webpack/issues/989)) ([4799271](https://github.com/NativeScript/nativescript-dev-webpack/commit/4799271)) +* escape the regex for the path to the entry module of application ([#998](https://github.com/NativeScript/nativescript-dev-webpack/issues/998)) ([571c7f2](https://github.com/NativeScript/nativescript-dev-webpack/commit/571c7f2)) + + + +## [1.0.1](https://github.com/NativeScript/nativescript-dev-webpack/compare/1.0.0...1.0.1) (2019-07-16) + + +### Bug Fixes + +* don't include partial scss files in bundle ([#988](https://github.com/NativeScript/nativescript-dev-webpack/issues/988)) ([786bd6c](https://github.com/NativeScript/nativescript-dev-webpack/commit/786bd6c)) +* **js:** try to resolve node_modules from the project root before resolving in a linked location ([#987](https://github.com/NativeScript/nativescript-dev-webpack/issues/987)) ([a3df142](https://github.com/NativeScript/nativescript-dev-webpack/commit/a3df142)) + + # [1.0.0](https://github.com/NativeScript/nativescript-dev-webpack/compare/0.24.1...1.0.0) (2019-07-10) diff --git a/bundle-config-loader.spec.ts b/bundle-config-loader.spec.ts new file mode 100644 index 00000000..ec8ad99b --- /dev/null +++ b/bundle-config-loader.spec.ts @@ -0,0 +1,114 @@ +import bundleConfigLoader from "./bundle-config-loader"; + +const defaultLoaderOptions = { + angular: false, + loadCss: true, + unitTesting: false, +}; + +const defaultTestFiles = { + "./app-root.xml": true, + "./app-root.land.xml": true, + "./app.ts": true, + "./app.css": true, + "./app.android.scss": true, + "./app.ios.scss": true, + "./app.land.css": true, + "./components/my-component.css": true, + "./components/my-component.land.ts": true, + "./components/my-component.ts": true, + "./components/my-component.land.xml": true, + "./components/my-component.xml": true, + "./components/my-component.land.css": true, + "./main/main-page.land.css": true, + "./main/main-page.css": true, + "./main/main-page.ts": true, + "./main/main-page.land.xml": true, + "./main/main-page.xml": true, + "./main/main-page.land.ts": true, + "./main/main-page-vm.ts": true, + + "./app_component.scss": true, + "./App_Resources123/some-file.xml": true, + "./MyApp_Resources/some-file.xml": true, + "./App_Resources_Nobody_Names_Folders_Like_That_Roska/some-file.xml": true, + + "./package.json": false, // do not include package.json files + "./app.d.ts": false, // do not include ts definitions + "./_app-common.scss": false, // do not include scss partial files + "./_app-variables.scss": false, // do not include scss partial files + "./App_Resources/Android/src/main/res/values/colors.xml": false, // do not include App_Resources + "./App_Resources/Android/src/main/AndroidManifest.xml": false, // do not include App_Resources +}; + +const loaderOptionsWithIgnore = { + angular: false, + loadCss: true, + unitTesting: false, + ignoredFiles: ["./application", "./activity"] +}; + +const ignoredTestFiles = { + "./application.ts": false, + "./activity.ts": false, +} + +function getRequireContextRegex(source: string): RegExp { + const requireContextStr = `require.context("~/", true, `; + + expect(source).toContain(requireContextStr); + + const start = source.indexOf(requireContextStr) + requireContextStr.length; + const end = source.indexOf(");\n", start); + const regexStr = source.substring(start, end); + const regex: RegExp = eval(regexStr); + + expect(regex instanceof RegExp).toBeTruthy(); + return regex; +} + +function assertTestFilesAreMatched(testFiles: { [key: string]: boolean }, regex: RegExp) { + for (let fileName in testFiles) { + if (defaultTestFiles[fileName]) { + expect(fileName).toMatch(regex); + } + else { + expect(fileName).not.toMatch(regex); + } + } +} + +describe("BundleConfigLoader should create require.context", () => { + it("default case", (done) => { + + const loaderContext = { + callback: (error, source: string, map) => { + const regex = getRequireContextRegex(source); + + assertTestFilesAreMatched(defaultTestFiles, regex); + + done(); + }, + query: defaultLoaderOptions + } + + bundleConfigLoader.call(loaderContext, " ___CODE___"); + }) + + it("with ignored files", (done) => { + + const loaderContext = { + callback: (error, source: string, map) => { + const regex = getRequireContextRegex(source); + const testFiles = { ...defaultTestFiles, ...ignoredTestFiles }; + + assertTestFilesAreMatched(testFiles, regex); + + done(); + }, + query: loaderOptionsWithIgnore + } + + bundleConfigLoader.call(loaderContext, " ___CODE___"); + }) +}); diff --git a/bundle-config-loader.ts b/bundle-config-loader.ts index f1f0458a..6732058c 100644 --- a/bundle-config-loader.ts +++ b/bundle-config-loader.ts @@ -4,7 +4,7 @@ import { getOptions } from "loader-utils"; import * as escapeRegExp from "escape-string-regexp"; // Matches all source, markup and style files that are not in App_Resources -const defaultMatch = "(? { module: { rules: [ { - test: nsWebpack.getEntryPathRegExp(appFullPath, entryPath), + include: join(appFullPath, entryPath), use: [ // Require all Android app components platform === "android" && { diff --git a/demo/JavaScriptApp/webpack.config.js b/demo/JavaScriptApp/webpack.config.js index ddcf17ea..ec4ea0b5 100644 --- a/demo/JavaScriptApp/webpack.config.js +++ b/demo/JavaScriptApp/webpack.config.js @@ -159,7 +159,7 @@ module.exports = env => { module: { rules: [ { - test: nsWebpack.getEntryPathRegExp(appFullPath, entryPath), + include: join(appFullPath, entryPath), use: [ // Require all Android app components platform === "android" && { diff --git a/demo/TypeScriptApp/webpack.config.js b/demo/TypeScriptApp/webpack.config.js index 9bc21ca6..64ad184c 100644 --- a/demo/TypeScriptApp/webpack.config.js +++ b/demo/TypeScriptApp/webpack.config.js @@ -165,7 +165,7 @@ module.exports = env => { module: { rules: [ { - test: nsWebpack.getEntryPathRegExp(appFullPath, entryPath), + include: join(appFullPath, entryPath), use: [ // Require all Android app components platform === "android" && { diff --git a/dependencyManager.js b/dependencyManager.js index 3364a779..7ed804de 100644 --- a/dependencyManager.js +++ b/dependencyManager.js @@ -10,17 +10,6 @@ Some dependencies have already been added. \ If you want to force update them, please run "node_modules/.bin/update-ns-webpack". `; -const USAGE_MESSAGE = ` -NativeScript Webpack plugin was successfully added. -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 Terser for minification. -For more information check out https://docs.nativescript.org/tooling/bundling-with-webpack#bundling. -`; - function addProjectDeps(packageJson, force = false) { packageJson.devDependencies = packageJson.devDependencies || {}; const postinstallOptions = { @@ -105,8 +94,6 @@ function dependsOn(packageJson, package) { } function showHelperMessages({ newDepsAdded, hasOldDeps }) { - console.info(USAGE_MESSAGE); - if (hasOldDeps) { console.info(ALREADY_ADDED_MESSAGE); } diff --git a/index.js b/index.js index 2ed399dc..7effb6c3 100644 --- a/index.js +++ b/index.js @@ -60,6 +60,11 @@ exports.getAppPath = (platform, projectDir) => { } }; +/** + * For backward compatibility. This method is deprecated. Do not use it anymore. + * This method also has a bug of not escaping valid regex symbols in entry path. + * For module rules use: "include" instead of "test". + */ exports.getEntryPathRegExp = (appFullPath, entryModule) => { const entryModuleFullPath = path.join(appFullPath, entryModule); // Windows paths contain `\`, so we need to convert each of the `\` to `\\`, so it will be correct inside RegExp diff --git a/index.spec.ts b/index.spec.ts index eda14f88..4e5471bb 100644 --- a/index.spec.ts +++ b/index.spec.ts @@ -1,5 +1,4 @@ -import { getConvertedExternals, getEntryPathRegExp } from './index'; -const path = require("path"); +import { getConvertedExternals } from './index'; describe('index', () => { describe('getConvertedExternals', () => { @@ -52,27 +51,4 @@ describe('index', () => { }); }); }); - - describe('getEntryPathRegExp', () => { - const originalPathJoin = path.join; - const entryModule = "index.js"; - - afterEach(() => { - path.join = originalPathJoin; - }); - - it('returns RegExp that matches Windows', () => { - const appPath = "D:\\Work\\app1\\app"; - path.join = path.win32.join; - const regExp = getEntryPathRegExp(appPath, entryModule); - expect(!!regExp.exec(`${appPath}\\${entryModule}`)).toBe(true); - }); - - it('returns RegExp that works with POSIX paths', () => { - const appPath = "/usr/local/lib/app1/app"; - path.join = path.posix.join; - const regExp = getEntryPathRegExp(appPath, entryModule); - expect(!!regExp.exec(`${appPath}/${entryModule}`)).toBe(true); - }); - }); }); diff --git a/package.json b/package.json index 90a97bf6..dd524ae9 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "preuninstall": "node preuninstall.js", "postpack": "rm -rf node_modules", "prepare": "npm run tsc && npm run jasmine", - "test": "npm run prepare && npm run jasmine", + "test": "npm run prepare", "jasmine": "jasmine --config=jasmine-config/jasmine.json", "version": "rm package-lock.json && conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md" }, @@ -91,4 +91,4 @@ "tns-core-modules": "next", "typescript": "~3.4.0" } -} +} \ No newline at end of file diff --git a/plugins/GenerateNativeScriptEntryPointsPlugin.js b/plugins/GenerateNativeScriptEntryPointsPlugin.js index 2d640e89..9417be22 100644 --- a/plugins/GenerateNativeScriptEntryPointsPlugin.js +++ b/plugins/GenerateNativeScriptEntryPointsPlugin.js @@ -1,3 +1,4 @@ +const { convertToUnixPath } = require("../lib/utils"); const { RawSource } = require("webpack-sources"); const { getPackageJson } = require("../projectHelpers"); const { SNAPSHOT_ENTRY_NAME } = require("./NativeScriptSnapshotPlugin"); @@ -55,7 +56,7 @@ exports.GenerateNativeScriptEntryPointsPlugin = (function () { entryChunk = chunk; } else { chunk.files.forEach(fileName => { - if (!this.isHMRFile(fileName)) { + if (!this.isHMRFile(fileName) && this.isSourceFile(fileName)) { requiredFiles.push(fileName); } }); @@ -71,14 +72,15 @@ exports.GenerateNativeScriptEntryPointsPlugin = (function () { throw new Error(`${GenerationFailedError} File "${filePath}" not found for entry "${entryPointName}".`); } - if (!this.isHMRFile(filePath)) { + if (!this.isHMRFile(filePath) && this.isSourceFile(filePath)) { const currFileDirRelativePath = path.dirname(filePath); const pathToRootFromCurrFile = path.relative(currFileDirRelativePath, "."); const requireDeps = requiredFiles.map(depPath => { const depRelativePath = path.join(pathToRootFromCurrFile, depPath); + const depRelativePathUnix = convertToUnixPath(depRelativePath); - return `require("./${depRelativePath}");`; + return `require("./${depRelativePathUnix}");`; }).join(""); const currentEntryFileContent = compilation.assets[filePath].source(); compilation.assets[filePath] = new RawSource(`${requireDeps}${currentEntryFileContent}`); @@ -96,5 +98,9 @@ exports.GenerateNativeScriptEntryPointsPlugin = (function () { return fileName.indexOf("hot-update") > -1; } + GenerateNativeScriptEntryPointsPlugin.prototype.isSourceFile = function (fileName) { + return fileName.endsWith(".js"); + } + return GenerateNativeScriptEntryPointsPlugin; })(); diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index d7cd1e78..fa623eee 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -197,7 +197,7 @@ module.exports = env => { module: { rules: [ { - test: nsWebpack.getEntryPathRegExp(appFullPath, entryPath), + include: join(appFullPath, entryPath), use: [ // Require all Android app components platform === "android" && { diff --git a/templates/webpack.config.spec.ts b/templates/webpack.config.spec.ts index eced35fc..024461bd 100644 --- a/templates/webpack.config.spec.ts +++ b/templates/webpack.config.spec.ts @@ -31,7 +31,6 @@ const nativeScriptDevWebpack = { getAppPath: () => 'app', getEntryModule: () => 'EntryModule', getResolver: () => null, - getEntryPathRegExp: () => null, getConvertedExternals: nsWebpackIndex.getConvertedExternals, getSourceMapFilename: nsWebpackIndex.getSourceMapFilename }; diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 2d004846..f9add996 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -96,13 +96,15 @@ module.exports = env => { extensions: [".js", ".scss", ".css"], // Resolve {N} system modules from tns-core-modules modules: [ + resolve(__dirname, "node_modules/tns-core-modules"), + resolve(__dirname, "node_modules"), "node_modules/tns-core-modules", "node_modules", ], alias: { '~': appFullPath }, - // don't resolve symlinks to symlinked modules + // resolve symlinks to symlinked modules symlinks: true }, resolveLoader: { @@ -159,7 +161,7 @@ module.exports = env => { module: { rules: [ { - test: nsWebpack.getEntryPathRegExp(appFullPath, entryPath), + include: join(appFullPath, entryPath), use: [ // Require all Android app components platform === "android" && { diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index a6bda652..9e0a3e84 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -164,7 +164,7 @@ module.exports = env => { module: { rules: [ { - test: nsWebpack.getEntryPathRegExp(appFullPath, entryPath), + include: join(appFullPath, entryPath), use: [ // Require all Android app components platform === "android" && { diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index b0539c0e..61068c7f 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -170,7 +170,7 @@ module.exports = env => { }, module: { rules: [{ - test: nsWebpack.getEntryPathRegExp(appFullPath, entryPath + ".(js|ts)"), + include: [join(appFullPath, entryPath + ".js"), join(appFullPath, entryPath + ".ts")], use: [ // Require all Android app components platform === "android" && {