diff --git a/.eslintrc.json b/.eslintrc.json index 8d58bdb49..1dee0b3ba 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -7,9 +7,10 @@ "project": ["packages/core/tsconfig.json", "packages/webpack/tsconfig.json"] }, "ignorePatterns": ["**/*"], - "plugins": ["@typescript-eslint", "@nrwl/nx"], - "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier", "prettier/@typescript-eslint"], + "plugins": ["prettier", "@typescript-eslint", "@nrwl/nx"], + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier/@typescript-eslint", "plugin:prettier/recommended"], "rules": { + "prettier/prettier": "warn", "@typescript-eslint/explicit-member-accessibility": "off", "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/no-parameter-properties": "off", diff --git a/.github/workflows/apps_automated.yml b/.github/workflows/apps_automated.yml new file mode 100644 index 000000000..e86d7efd0 --- /dev/null +++ b/.github/workflows/apps_automated.yml @@ -0,0 +1,39 @@ +name: 'apps/automated' + +on: + push: + branches: + - master + pull_request: + workflow_dispatch: + +jobs: + test: + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + + - name: Install Python + uses: actions/setup-python@v1 + + - name: Install NativeScript + run: | + python -m pip install --upgrade pip six + npm i -g nativescript --ignore-scripts + ns usage-reporting disable + ns error-reporting disable + ns doctor + + - name: Setup + run: npm run setup + + - name: Create Emulator + uses: rigor789/action-create-emulator@master + + - name: Test (Android) + run: node tools/scripts/run-automated.js android + + - name: Test (iOS) + if: always() # run iOS tests even if Android tests failed + run: node tools/scripts/run-automated.js ios diff --git a/.github/workflows/npm_release_core.yml b/.github/workflows/npm_release_core.yml index 9dd0d58c8..2e3b8278c 100644 --- a/.github/workflows/npm_release_core.yml +++ b/.github/workflows/npm_release_core.yml @@ -5,6 +5,7 @@ on: branches: [ 'master' ] paths: - 'packages/core/**' + workflow_dispatch: env: NPM_TAG: 'next' @@ -17,7 +18,7 @@ jobs: - uses: actions/checkout@v2 - name: Setup - run: npm install + run: npm run setup - name: Generate Version working-directory: packages/core diff --git a/.github/workflows/npm_release_tns_core.yml b/.github/workflows/npm_release_tns_core.yml new file mode 100644 index 000000000..e8dc19060 --- /dev/null +++ b/.github/workflows/npm_release_tns_core.yml @@ -0,0 +1,74 @@ +name: 'tns-core-modules -> npm' + +on: + push: + branches: [ 'tns-core-modules' ] + paths: + - 'nativescript-core/**' + workflow_dispatch: + +env: + NPM_TAG: 'tns-next' + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Setup + run: npm install + + - name: Generate Version + run: | + echo NPM_VERSION=$(node -e "console.log(require('./package.json').version);")-$NPM_TAG-$(date +"%m-%d-%Y")-$GITHUB_RUN_ID >> $GITHUB_ENV + + - name: Bump Versions + run: | + # bump root version + npm version --no-git-tag-version $NPM_VERSION + + # bump @nativescript/core + cd nativescript-core + npm version --no-git-tag-version $NPM_VERSION + cd .. + + # bump tns-core-modules version & @nativescript/core dep + cd tns-core-modules-package + npm version --no-git-tag-version $NPM_VERSION + cat < _bump_core.js + const {readFileSync: read, writeFileSync: write} = require('fs'), + p = 'package.json', + pkg = read(p).toString() + ver = process.argv.splice(2).join(' '); + u = pkg.replace(/("@nativescript\/core": ")(?:.+)(")/g, \`\$1\${ver}\$2\`); + console.log(u) + write(p, u); + EOT + node _bump_core.js $NPM_VERSION + + # for debugging - just show diff + git diff package.json + cd .. + + - name: Build @nativescript/core + run: npm run build-core + + - name: Build tns-core-modules + run: npm run build-compat + + - name: Publish @nativescript/core + working-directory: dist + env: + NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} + run: | + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ../.npmrc + + ls -al + + echo "Publishing @nativescript/core@$NPM_VERSION to NPM with tag $NPM_TAG..." + # npm publish nativescript-core-$NPM_VERSION.tgz --tag $NPM_TAG --dry-run + + echo "Publishing tns-core-modules@$NPM_VERSION to NPM with tag $NPM_TAG..." + # npm publish tns-core-modules-$NPM_VERSION.tgz --tag $NPM_TAG --dry-run diff --git a/.prettierignore b/.prettierignore index 2ad39857b..d10e2e5be 100644 --- a/.prettierignore +++ b/.prettierignore @@ -16,9 +16,10 @@ packages/ui-mobile-base tools/assets/App_Resources *.cmd *.md -*.json +package.json *.js *.map *.css *.scss -*.sh \ No newline at end of file +*.sh +!packages/webpack/templates/*.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 78d1eb13a..48dcb6061 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,50 @@ +## [7.2.1](https://github.com/NativeScript/NativeScript/compare/7.2.0-core...7.2.1) (2021-02-07) + + +### Bug Fixes + +* **core:** conflicting node global types ([#9197](https://github.com/NativeScript/NativeScript/issues/9197)) ([de7006b](https://github.com/NativeScript/NativeScript/commit/de7006b04d1fb2209b8f6efeafbc2a16d4a1d83d)) + + + +# [7.2.0](https://github.com/NativeScript/NativeScript/compare/7.1.4-core...7.2.0) (2021-02-05) + + +### Bug Fixes + +* **core:** ObservableArray splice with start only ([#9159](https://github.com/NativeScript/NativeScript/issues/9159)) ([3ddfb5c](https://github.com/NativeScript/NativeScript/commit/3ddfb5c34a3f7d7ad9d092a87b1cfebbc2ab5b07)) +* **ios:** allow navigationFrom event for deep navigation within modal frame ([#9187](https://github.com/NativeScript/NativeScript/issues/9187)) ([8f1455e](https://github.com/NativeScript/NativeScript/commit/8f1455eef71a4feaaffe4fb2aca4e49da0bc0670)) +* **ios:** force release of nsdata after saving image ([#9177](https://github.com/NativeScript/NativeScript/issues/9177)) ([e002d72](https://github.com/NativeScript/NativeScript/commit/e002d72d41b7a006788fcd38feb51a7b3c1ef870)) +* **ios:** navigation via swipe crash fix ([#9132](https://github.com/NativeScript/NativeScript/issues/9132)) ([28061e3](https://github.com/NativeScript/NativeScript/commit/28061e3d39fe713d78f1191a5c7e31dda7941ac1)) +* **ios:** textfield resizing (auto width) on text change ([#9176](https://github.com/NativeScript/NativeScript/issues/9176)) ([c31bab1](https://github.com/NativeScript/NativeScript/commit/c31bab1bf73af7f90ff3c5c90a22b86a682137ea)) +* **page:** frame getter for custom Frames ([#9195](https://github.com/NativeScript/NativeScript/issues/9195)) ([6da7d90](https://github.com/NativeScript/NativeScript/commit/6da7d90e256d220db79e245228b91d5fa8e41984)) +* **webpack:** --env.uglify works properly now ([#9165](https://github.com/NativeScript/NativeScript/issues/9165)) ([be52cef](https://github.com/NativeScript/NativeScript/commit/be52cefe672aaca6d707c1c3b78cee7ee8abe8f1)) +* **webpack:** Angular no longer has issues handling {N} plugins without nativescript in name ([#9172](https://github.com/NativeScript/NativeScript/issues/9172)) ([79a5fc8](https://github.com/NativeScript/NativeScript/commit/79a5fc89750ea467a2d44d5d9b5264c9fdad1a94)) +* **webpack:** inspector_modules ([87418cd](https://github.com/NativeScript/NativeScript/commit/87418cdb119e4114285be81999968438d2094929)) + + +### Features + +* **android:** FlexboxLayout support for isPassThroughParentEnabled ([#8798](https://github.com/NativeScript/NativeScript/issues/8798)) ([5fe2742](https://github.com/NativeScript/NativeScript/commit/5fe27428e07a267454a5fcfa8584ba688bf0baef)) +* **core:** setSelection method for editable text components ([#9175](https://github.com/NativeScript/NativeScript/issues/9175)) ([58b2542](https://github.com/NativeScript/NativeScript/commit/58b254299770b362e0c5baee36000ec81b57335a)) +* **ios:** build TNSWidgets as XCFramework ([#9167](https://github.com/NativeScript/NativeScript/issues/9167)) ([04a7641](https://github.com/NativeScript/NativeScript/commit/04a76415b785ca419d057d570fc71f61b7d3bb83)) +* **webpack:** allow passing env.appComponents and env.entries ([#8898](https://github.com/NativeScript/NativeScript/issues/8898)) ([90d208c](https://github.com/NativeScript/NativeScript/commit/90d208c115b582e37844494d10b0eaf6a3d74122)) + + +### Performance Improvements + +* **android:** faster background color setter ([#9120](https://github.com/NativeScript/NativeScript/issues/9120)) ([e501273](https://github.com/NativeScript/NativeScript/commit/e501273d166b0e6f8b3746d508e97099525cea0a)) + + +## [7.1.4](https://github.com/NativeScript/NativeScript/compare/7.1.3-core...7.1.4) (2021-01-23) + + +### Bug Fixes + +* **ios:** getVisibleViewController maximum call stack exceeded ([#9168](https://github.com/NativeScript/NativeScript/issues/9168)) ([1a3523e](https://github.com/NativeScript/NativeScript/commit/1a3523ef22f15574ce5658429a4c18eb141ab881)) + + + ## [7.1.3](https://github.com/NativeScript/NativeScript/compare/7.1.2-core...7.1.3) (2021-01-17) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..09827eb16 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at . All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/README.md b/README.md index 7bb49109f..422774c96 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ $ npm start We love you and PR's 🤗 Please follow our [contributing guide](https://github.com/NativeScript/NativeScript/blob/master/tools/notes/CONTRIBUTING.md) and see [our code of governance](https://nativescript.org/governance/) to become as involved as you want to be. -## @nativescript/* +## @nativescript/* * [@nativescript/core](https://github.com/NativeScript/NativeScript/tree/master/packages/core) * Core iOS/Android for NativeScript @@ -59,16 +59,16 @@ We love you and PR's 🤗 Please follow our [contributing guide](https://github. - [NativeScript marketplace](https://market.nativescript.org/) - [NativeScript roadmap](https://www.nativescript.org/roadmap) -## Other framework source repos +## Other framework source repositories -Outside of the source centralized in this repo, the NativeScript framework consists of a number of components, all of which are open source and on GitHub. Here are the major ones: +Outside of the source centralized in this repo, the NativeScript framework consists of a number of components, all of which are open source available on GitHub. Here are the major ones: - **[iOS runtime](https://github.com/NativeScript/ns-v8ios-runtime)** - [![npm](https://img.shields.io/npm/dm/tns-ios.svg)](https://www.npmjs.com/package/@nativescript/ios) - This repo contains the NativeScript iOS runtime — the code that hosts NativeScript iOS apps, and allows JavaScript code to be executed on iOS devices. The iOS runtime is written in a fun mix of C++, Objective-C, and more. - **[Android runtime](https://github.com/NativeScript/android-runtime)** - [![npm](https://img.shields.io/npm/dm/tns-android.svg)](https://www.npmjs.com/package/tns-android) - - This repo contains the NativeScript Android — the code that hosts NativeScript Android apps, and allows JavaScript code to be executed on Android devices. The Android runtime is written in a fun mix of C++ and Java. + - This repo contains the NativeScript Android runtime — the code that hosts NativeScript Android apps, and allows JavaScript code to be executed on Android devices. The Android runtime is written in a fun mix of C++ and Java. - **[CLI](//github.com/NativeScript/nativescript-cli)** - [![npm](https://img.shields.io/npm/dm/nativescript.svg)](https://www.npmjs.com/package/nativescript) - This repo contains the NativeScript command-line interface, which lets you create, build, and run apps using the NativeScript framework. The CLI is written in TypeScript. @@ -76,9 +76,9 @@ Outside of the source centralized in this repo, the NativeScript framework consi - [![Docs](https://img.shields.io/badge/Docs-NativeScript-brightgreen)](https://docs.nativescript.org/) - This repo contains the NativeScript framework documentation, which is available at . The docs are written in Markdown. -In addition to the code that makes up the NativeScript framework itself, we also provide a number of [open-source sample apps](https://www.nativescript.org/app-samples-with-code) that you can reference while building your NativeScript application. +In addition to the code that makes up the NativeScript framework itself, we also provide a number of [open-source sample apps](https://www.nativescript.org/app-samples-with-code) from which you can take reference while building your NativeScript application. ## License -[Apache License 2.0](https://github.com/NativeScript/NativeScript/blob/master/LICENSE) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/NativeScript/NativeScript/blob/master/LICENSE)

Made with ❤️

diff --git a/apps/automated/.gitignore b/apps/automated/.gitignore new file mode 100644 index 000000000..a6a2bfdd5 --- /dev/null +++ b/apps/automated/.gitignore @@ -0,0 +1 @@ +!webpack.custom.config.js diff --git a/apps/automated/nativescript.config.ts b/apps/automated/nativescript.config.ts index e93d59166..e69de915a 100644 --- a/apps/automated/nativescript.config.ts +++ b/apps/automated/nativescript.config.ts @@ -3,6 +3,7 @@ import { NativeScriptConfig } from '@nativescript/core'; export default { id: 'org.nativescript.UnitTestApp', appResourcesPath: '../../tools/assets/App_Resources', + webpackConfigPath: 'webpack.custom.config.js', android: { v8Flags: '--expose_gc', markingMode: 'none', diff --git a/apps/automated/package.json b/apps/automated/package.json index 67a19b86e..9198b309f 100644 --- a/apps/automated/package.json +++ b/apps/automated/package.json @@ -15,7 +15,7 @@ }, "devDependencies": { "@nativescript/android": "7.0.1", - "@nativescript/ios": "7.1.0", + "@nativescript/ios": "7.2.0", "@nativescript/webpack": "file:../../dist/packages/nativescript-webpack.tgz", "typescript": "file:../../node_modules/typescript" }, diff --git a/apps/automated/src/globals.d.ts b/apps/automated/src/globals.d.ts new file mode 100644 index 000000000..d5ddcaec7 --- /dev/null +++ b/apps/automated/src/globals.d.ts @@ -0,0 +1 @@ +declare var __CI__; diff --git a/apps/automated/src/http/http-string-worker.ts b/apps/automated/src/http/http-string-worker.ts index 4c446b95a..629acf1d6 100644 --- a/apps/automated/src/http/http-string-worker.ts +++ b/apps/automated/src/http/http-string-worker.ts @@ -1,8 +1,8 @@ -import * as http from '@nativescript/core/http'; +import { Http } from '@nativescript/core'; declare var postMessage: any; -http.getString('https://httpbin.org/get').then( +Http.getString('https://httpbin.org/get').then( function (r) { postMessage(r); }, diff --git a/apps/automated/src/http/http-tests.ts b/apps/automated/src/http/http-tests.ts index 3b52d07f4..d60eafbf1 100644 --- a/apps/automated/src/http/http-tests.ts +++ b/apps/automated/src/http/http-tests.ts @@ -1,4 +1,4 @@ -import { ImageSource } from '@nativescript/core/image-source'; +import { ImageSource } from '@nativescript/core'; import * as TKUnit from '../tk-unit'; import * as http from '@nativescript/core/http'; import * as fs from '@nativescript/core/file-system'; @@ -697,7 +697,7 @@ export var test_getString_WorksProperlyInWorker = function (done) { done(); }; worker.onerror = function (e) { - console.log('errir received'); + console.log('error received'); done(e); }; }; diff --git a/apps/automated/src/test-runner.ts b/apps/automated/src/test-runner.ts index a5189faf6..5191ee291 100644 --- a/apps/automated/src/test-runner.ts +++ b/apps/automated/src/test-runner.ts @@ -32,25 +32,25 @@ allTests['GLOBALS'] = globalsTests; import * as domNodeTest from './debugger/dom-node-tests'; allTests['DOM-NODE'] = domNodeTest; -import * as profilingTests from './profiling/profiling-tests'; -allTests['PROFILING'] = profilingTests; - import * as platformTests from './platform/platform-tests'; allTests['PLATFORM'] = platformTests; import * as fsTests from './file-system/file-system-tests'; allTests['FILE-SYSTEM'] = fsTests; -// Disabled tests as they have external dependencies -// TODO: find a way to run these tests locally, but don't run them on the CI as they are flaky -// import * as httpTests from "./http/http-tests"; -// allTests["HTTP"] = httpTests; - -// import * as xhrTests from "./xhr/xhr-tests"; -// allTests["XHR"] = xhrTests; - -// import * as fetchTests from "./fetch/fetch-tests"; -// allTests["FETCH"] = fetchTests; +import * as httpTests from './http/http-tests'; +import * as xhrTests from './xhr/xhr-tests'; +import * as fetchTests from './fetch/fetch-tests'; +import * as timerTests from './timer/timer-tests'; +import * as profilingTests from './profiling/profiling-tests'; +// don't run these on CI as they are flaky +if (!__CI__) { + allTests['HTTP'] = httpTests; + allTests['XHR'] = xhrTests; + allTests['FETCH'] = fetchTests; + allTests['TIMER'] = timerTests; + allTests['PROFILING'] = profilingTests; +} import * as appSettingsTests from './application-settings/application-settings-tests'; allTests['APPLICATION-SETTINGS'] = appSettingsTests; @@ -70,9 +70,6 @@ allTests['VIRTUAL-ARRAY'] = virtualArrayTests; import * as observableTests from './data/observable-tests'; allTests['OBSERVABLE'] = observableTests; -import * as timerTests from './timer/timer-tests'; -allTests['TIMER'] = timerTests; - import * as animationFrameTests from './animation-frame/animation-frame'; allTests['ANIMATION-FRAME'] = animationFrameTests; @@ -197,8 +194,7 @@ import * as bottomNavigationTestsNew from './ui/bottom-navigation/bottom-navigat allTests['BOTTOM-NAVIGATION-NEW'] = bottomNavigationTestsNew; import * as bottomNavigationNavigationTests from './ui/bottom-navigation/bottom-navigation-navigation-tests'; -// TODO: uncomment this -// allTests["BOTTOM-NAVIGATION-NAVIGATION"] = bottomNavigationNavigationTests; +isIOS && (allTests['BOTTOM-NAVIGATION-NAVIGATION'] = bottomNavigationNavigationTests); import * as tabViewTests from './ui/tab-view/tab-view-tests'; allTests['TAB-VIEW'] = tabViewTests; @@ -291,8 +287,8 @@ import * as bottomNavigationRootTests from './ui/bottom-navigation/bottom-naviga allTests['BOTTOM-NAVIGATION-ROOT'] = bottomNavigationRootTests; // Reset root view didn't work with android tabs -// import * as tabsRootTests from "./ui/tabs/tabs-root-tests"; -// allTests["TABS-ROOT"] = tabsRootTests; +import * as tabsRootTests from './ui/tabs/tabs-root-tests'; +isIOS && (allTests['TABS-ROOT'] = tabsRootTests); import * as resetRootViewTests from './ui/root-view/reset-root-view-tests'; allTests['RESET-ROOT-VIEW'] = resetRootViewTests; diff --git a/apps/automated/src/timer/timer-tests.ts b/apps/automated/src/timer/timer-tests.ts index 4f8f10bbb..7c4852098 100644 --- a/apps/automated/src/timer/timer-tests.ts +++ b/apps/automated/src/timer/timer-tests.ts @@ -155,6 +155,7 @@ export function test_setInterval_callbackCalledDuringPeriod(done) { export function test_setInterval_callbackCalledWithExtraArgs(done) { let counter: number = 0; const rnd: number = Math.random(); + const threshold = 100; const start = TKUnit.time(); const id = timer.setInterval( @@ -163,10 +164,10 @@ export function test_setInterval_callbackCalledWithExtraArgs(done) { if (counter === 4) { const end = TKUnit.time(); timer.clearInterval(id); - done(end - start > 250 ? new Error('setInterval too slow.') : null); + done(end - start > 1000 + threshold ? new Error('setInterval too slow.') : null); } }, - 50, + 250, rnd ); } @@ -179,11 +180,11 @@ export function test_setInterval_callbackNotDelayedByBusyWork() { calls++; if (firstCall) { firstCall = false; - TKUnit.wait(0.025); + TKUnit.wait(0.125); } - }, 50); + }, 250); - TKUnit.wait(0.11); + TKUnit.wait(0.55); timer.clearInterval(id); TKUnit.assertEqual(calls, 2, 'Callback should be called multiple times with busy wait'); } diff --git a/apps/automated/src/tk-unit.ts b/apps/automated/src/tk-unit.ts index fce07495c..c875f60f4 100644 --- a/apps/automated/src/tk-unit.ts +++ b/apps/automated/src/tk-unit.ts @@ -347,7 +347,7 @@ export function wait(seconds: number): void { waitUntilReady(() => false, seconds, false); } -export function waitUntilReady(isReady: () => boolean, timeoutSec: number = 3, shouldThrow: boolean = true) { +export function waitUntilReady(isReady: () => boolean, timeoutSec: number = 5, shouldThrow: boolean = true) { if (!isReady) { return; } diff --git a/apps/automated/src/ui/button/button-tests-native.android.ts b/apps/automated/src/ui/button/button-tests-native.android.ts index 759c16c66..d17d73298 100644 --- a/apps/automated/src/ui/button/button-tests-native.android.ts +++ b/apps/automated/src/ui/button/button-tests-native.android.ts @@ -1,53 +1,53 @@ -import * as buttonModule from '@nativescript/core/ui/button'; -import * as colorModule from '@nativescript/core/color'; -import * as utilsModule from '@nativescript/core/utils/utils'; -import * as enums from '@nativescript/core/ui/enums'; +import { Color, Button, Utils, Enums } from '@nativescript/core'; -export function getNativeText(button: buttonModule.Button): string { +export function getNativeText(button: Button): string { return button.android.getText(); } -export function getNativeTextWrap(button: buttonModule.Button): boolean { +export function getNativeTextWrap(button: Button): boolean { return (button.android).getLineCount() === 1; } -export function getNativeFontSize(button: buttonModule.Button): number { - var density = utilsModule.layout.getDisplayDensity(); +export function getNativeFontSize(button: Button): number { + let density = Utils.layout.getDisplayDensity(); return button.android.getTextSize() / density; } -export function getNativeColor(button: buttonModule.Button): colorModule.Color { - return new colorModule.Color(button.android.getTextColors().getDefaultColor()); +export function getNativeColor(button: Button): Color { + return new Color(button.android.getTextColors().getDefaultColor()); } -export function getNativeBackgroundColor(button: buttonModule.Button): colorModule.Color { - var bkg = button.android.getBackground(); - if (bkg instanceof org.nativescript.widgets.BorderDrawable) { - return new colorModule.Color((bkg).getBackgroundColor()); +export function getNativeBackgroundColor(button: Button): Color { + let bg = button.android.getBackground(); + if (bg instanceof org.nativescript.widgets.BorderDrawable) { + return new Color(bg.getBackgroundColor()); + } else if (bg instanceof android.graphics.drawable.ColorDrawable) { + console.log(bg); + return new Color(bg.getColor()); } else { - return new colorModule.Color(bkg.backgroundColor); + return new Color(bg.backgroundColor); } } -export function getNativeTextAlignment(button: buttonModule.Button): string { - var gravity = button.android.getGravity(); +export function getNativeTextAlignment(button: Button): string { + let gravity = button.android.getGravity(); if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.LEFT) { - return enums.TextAlignment.left; + return Enums.TextAlignment.left; } if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.CENTER_HORIZONTAL) { - return enums.TextAlignment.center; + return Enums.TextAlignment.center; } if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.RIGHT) { - return enums.TextAlignment.right; + return Enums.TextAlignment.right; } return 'unexpected value'; } -export function performNativeClick(button: buttonModule.Button): void { +export function performNativeClick(button: Button): void { button.android.performClick(); } diff --git a/apps/automated/src/ui/label/label-tests-native.android.ts b/apps/automated/src/ui/label/label-tests-native.android.ts index ee4fe6090..025c189a6 100644 --- a/apps/automated/src/ui/label/label-tests-native.android.ts +++ b/apps/automated/src/ui/label/label-tests-native.android.ts @@ -3,7 +3,7 @@ import * as enums from '@nativescript/core/ui/enums'; import * as colorModule from '@nativescript/core/color'; export function getNativeTextAlignment(label: labelModule.Label): string { - var gravity = label.android.getGravity(); + let gravity = label.android.getGravity(); if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.LEFT) { return enums.TextAlignment.left; @@ -21,10 +21,12 @@ export function getNativeTextAlignment(label: labelModule.Label): string { } export function getNativeBackgroundColor(label: labelModule.Label): colorModule.Color { - var bkg = label.android.getBackground(); - if (bkg instanceof org.nativescript.widgets.BorderDrawable) { - return new colorModule.Color((bkg).getBackgroundColor()); + let bg = label.android.getBackground(); + if (bg instanceof org.nativescript.widgets.BorderDrawable) { + return new colorModule.Color(bg.getBackgroundColor()); + } else if (bg instanceof android.graphics.drawable.ColorDrawable) { + return new colorModule.Color(bg.getColor()); } else { - return new colorModule.Color(bkg.backgroundColor); + return new colorModule.Color(bg.backgroundColor); } } diff --git a/apps/automated/src/ui/label/label-tests.ts b/apps/automated/src/ui/label/label-tests.ts index 0383375b5..259668ee2 100644 --- a/apps/automated/src/ui/label/label-tests.ts +++ b/apps/automated/src/ui/label/label-tests.ts @@ -330,8 +330,8 @@ export class LabelTest extends testModule.UITest { normalColor = actualColors.getDefaultColor(); TKUnit.assert(normalColor, 'Expected: ' + expColor + ', Actual: ' + normalColor); - const bkg = testLabel.android.getBackground(); - actualBackgroundColor = bkg.getBackgroundColor(); + const bg = testLabel.android.getBackground(); + actualBackgroundColor = bg['getBackgroundColor'] ? bg.getBackgroundColor() : bg.getColor(); expBackgroundColor = android.graphics.Color.parseColor(backgroundColor); TKUnit.assertEqual(actualBackgroundColor, expBackgroundColor); } else { diff --git a/apps/automated/src/ui/text-field/text-field-tests-native.android.ts b/apps/automated/src/ui/text-field/text-field-tests-native.android.ts index 55b892a24..adddb5843 100644 --- a/apps/automated/src/ui/text-field/text-field-tests-native.android.ts +++ b/apps/automated/src/ui/text-field/text-field-tests-native.android.ts @@ -1,74 +1,74 @@ -import * as textFieldModule from '@nativescript/core/ui/text-field'; -import * as colorModule from '@nativescript/core/color'; -import * as utilsModule from '@nativescript/core/utils/utils'; -import * as enums from '@nativescript/core/ui/enums'; +import { TextField, Color, Utils, Enums } from '@nativescript/core'; -export function getNativeText(textField: textFieldModule.TextField): string { +export function getNativeText(textField: TextField): string { return textField.android.getText().toString(); } -export function getNativeHint(textField: textFieldModule.TextField): string { +export function getNativeHint(textField: TextField): string { return textField.android.getHint(); } -export function getNativeSecure(textField: textFieldModule.TextField): boolean { - var inputType = textField.android.getInputType(); +export function getNativeSecure(textField: TextField): boolean { + let inputType = textField.android.getInputType(); return (inputType & android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD) === android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD || (inputType & android.text.InputType.TYPE_NUMBER_VARIATION_PASSWORD) === android.text.InputType.TYPE_NUMBER_VARIATION_PASSWORD; } -export function getNativeFontSize(textField: textFieldModule.TextField): number { - var density = utilsModule.layout.getDisplayDensity(); +export function getNativeFontSize(textField: TextField): number { + let density = Utils.layout.getDisplayDensity(); return textField.android.getTextSize() / density; } -export function getNativeColor(textField: textFieldModule.TextField): colorModule.Color { - return new colorModule.Color(textField.android.getTextColors().getDefaultColor()); +export function getNativeColor(textField: TextField): Color { + return new Color(textField.android.getTextColors().getDefaultColor()); } -export function getNativePlaceholderColor(textField: textFieldModule.TextField): colorModule.Color { - return new colorModule.Color(textField.android.getHintTextColors().getDefaultColor()); +export function getNativePlaceholderColor(textField: TextField): Color { + return new Color(textField.android.getHintTextColors().getDefaultColor()); } -export function getNativeBackgroundColor(textField: textFieldModule.TextField): colorModule.Color { - var bkg = textField.android.getBackground(); - if (bkg instanceof org.nativescript.widgets.BorderDrawable) { - return new colorModule.Color((bkg).getBackgroundColor()); +export function getNativeBackgroundColor(textField: TextField): Color { + let bg = textField.android.getBackground(); + if (bg instanceof org.nativescript.widgets.BorderDrawable) { + return new Color(bg.getBackgroundColor()); + } else if (bg instanceof android.graphics.drawable.ColorDrawable) { + console.log(bg); + return new Color(bg.getColor()); } else { - return new colorModule.Color(bkg.backgroundColor); + return new Color(bg.backgroundColor); } } -export function getNativeTextAlignment(textField: textFieldModule.TextField): string { +export function getNativeTextAlignment(textField: TextField): string { var gravity = textField.android.getGravity(); if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.LEFT) { - return enums.TextAlignment.left; + return Enums.TextAlignment.left; } if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.CENTER_HORIZONTAL) { - return enums.TextAlignment.center; + return Enums.TextAlignment.center; } if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.RIGHT) { - return enums.TextAlignment.right; + return Enums.TextAlignment.right; } return 'unexpected value'; } -export function getNativeFocus(textField: textFieldModule.TextField): boolean { +export function getNativeFocus(textField: TextField): boolean { // return true; } -export function typeTextNatively(textField: textFieldModule.TextField, text: string): void { +export function typeTextNatively(textField: TextField, text: string): void { textField.android.requestFocus(); textField.android.setText(text); textField.android.clearFocus(); } -export function typeTextNativelyWithReturn(textField: textFieldModule.TextField, text: string): void { +export function typeTextNativelyWithReturn(textField: TextField, text: string): void { // } diff --git a/apps/automated/src/ui/text-view/text-view-tests-native.android.ts b/apps/automated/src/ui/text-view/text-view-tests-native.android.ts index 016cdb81e..d3bb5c13e 100644 --- a/apps/automated/src/ui/text-view/text-view-tests-native.android.ts +++ b/apps/automated/src/ui/text-view/text-view-tests-native.android.ts @@ -1,13 +1,10 @@ -import * as textViewModule from '@nativescript/core/ui/text-view'; -import * as colorModule from '@nativescript/core/color'; -import * as utilsModule from '@nativescript/core/utils/utils'; -import * as enums from '@nativescript/core/ui/enums'; +import { TextView, Color, Utils, Enums } from '@nativescript/core'; -export function getNativeText(textView: textViewModule.TextView): string { +export function getNativeText(textView: TextView): string { return textView.android.getText().toString(); } -export function getNativeEditable(textView: textViewModule.TextView): boolean { +export function getNativeEditable(textView: TextView): boolean { if (textView.android.getKeyListener()) { return true; } else { @@ -15,53 +12,55 @@ export function getNativeEditable(textView: textViewModule.TextView): boolean { } } -export function getNativeHint(textView: textViewModule.TextView): string { +export function getNativeHint(textView: TextView): string { return textView.android.getHint(); } -export function getNativeFontSize(textView: textViewModule.TextView): number { - var density = utilsModule.layout.getDisplayDensity(); +export function getNativeFontSize(textView: TextView): number { + let density = Utils.layout.getDisplayDensity(); return textView.android.getTextSize() / density; } -export function getNativeColor(textView: textViewModule.TextView): colorModule.Color { - return new colorModule.Color(textView.android.getTextColors().getDefaultColor()); +export function getNativeColor(textView: TextView): Color { + return new Color(textView.android.getTextColors().getDefaultColor()); } -export function getNativeBackgroundColor(textView: textViewModule.TextView): colorModule.Color { - var bkg = textView.android.getBackground(); - if (bkg instanceof org.nativescript.widgets.BorderDrawable) { - return new colorModule.Color((bkg).getBackgroundColor()); +export function getNativeBackgroundColor(textView: TextView): Color { + let bg = textView.android.getBackground(); + if (bg instanceof org.nativescript.widgets.BorderDrawable) { + return new Color(bg.getBackgroundColor()); + } else if (bg instanceof android.graphics.drawable.ColorDrawable) { + return new Color(bg.getColor()); } else { - return new colorModule.Color(bkg.backgroundColor); + return new Color(bg.backgroundColor); } } -export function getNativeTextAlignment(textView: textViewModule.TextView): string { - var gravity = textView.android.getGravity(); +export function getNativeTextAlignment(textView: TextView): string { + let gravity = textView.android.getGravity(); if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.LEFT) { - return enums.TextAlignment.left; + return Enums.TextAlignment.left; } if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.CENTER_HORIZONTAL) { - return enums.TextAlignment.center; + return Enums.TextAlignment.center; } if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.RIGHT) { - return enums.TextAlignment.right; + return Enums.TextAlignment.right; } return 'unexpected value'; } -export function typeTextNatively(textView: textViewModule.TextView, text: string): void { +export function typeTextNatively(textView: TextView, text: string): void { textView.android.requestFocus(); textView.android.setText(text); textView.android.clearFocus(); } -export function getNativeMaxLines(textView: textViewModule.TextView): number { +export function getNativeMaxLines(textView: TextView): number { return textView.android.getMaxLines(); } diff --git a/apps/automated/webpack.custom.config.js b/apps/automated/webpack.custom.config.js new file mode 100644 index 000000000..f13fc0393 --- /dev/null +++ b/apps/automated/webpack.custom.config.js @@ -0,0 +1,19 @@ +const webpack = require('webpack'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +const webpackConfig = require('./webpack.config'); + +module.exports = (env) => { + env = env || {}; + const baseConfig = webpackConfig(env); + + baseConfig.plugins.push(new CopyWebpackPlugin([ + { from: { glob: 'ui/web-view/*.html', dot: false } } + ])) + + baseConfig.plugins.push(new webpack.DefinePlugin({ + __CI__: !!process.env.CI + })) + + return baseConfig; +}; diff --git a/apps/toolbox/package.json b/apps/toolbox/package.json index 4bca9f519..b48c530fa 100644 --- a/apps/toolbox/package.json +++ b/apps/toolbox/package.json @@ -12,7 +12,7 @@ }, "devDependencies": { "@nativescript/android": "7.0.1", - "@nativescript/ios": "7.1.0", + "@nativescript/ios": "7.2.0", "@nativescript/webpack": "file:../../dist/packages/nativescript-webpack.tgz", "typescript": "file:../../node_modules/typescript" } diff --git a/apps/ui/package.json b/apps/ui/package.json index 600d2fd41..a28bb6f74 100644 --- a/apps/ui/package.json +++ b/apps/ui/package.json @@ -12,7 +12,7 @@ }, "devDependencies": { "@nativescript/android": "7.0.1", - "@nativescript/ios": "7.1.0", + "@nativescript/ios": "7.2.0", "@nativescript/webpack": "file:../../dist/packages/nativescript-webpack.tgz", "typescript": "file:../../node_modules/typescript" }, diff --git a/apps/ui/src/flexbox/flexbox-ispassthroughparent-page.ts b/apps/ui/src/flexbox/flexbox-ispassthroughparent-page.ts new file mode 100644 index 000000000..90ea4e5a5 --- /dev/null +++ b/apps/ui/src/flexbox/flexbox-ispassthroughparent-page.ts @@ -0,0 +1,11 @@ +export function onStackLayoutTapped(args) { + console.log('The StackLayout is tapped (called method: onStackLayoutTapped)'); + // Some visual action to execute when the tap is triggered + args.object.backgroundColor = !args.object.backgroundColor || args.object.backgroundColor.toString() !== '#FFFF00' ? '#FFFF00' : '#FFFFFF'; +} + +export function onFlexLayoutTap(args) { + console.log('The FlexboxLayout is tapped (called method: onFlexLayoutTap)'); + // Some visual action to execute when the tap is triggered + args.object.backgroundColor = !args.object.backgroundColor || args.object.backgroundColor.toString() !== '#FFFF00' ? '#FFFF00' : '#FFFFFF'; +} diff --git a/apps/ui/src/flexbox/flexbox-ispassthroughparent-page.xml b/apps/ui/src/flexbox/flexbox-ispassthroughparent-page.xml new file mode 100644 index 000000000..83c784f07 --- /dev/null +++ b/apps/ui/src/flexbox/flexbox-ispassthroughparent-page.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/apps/ui/src/flexbox/flexbox-main-page.ts b/apps/ui/src/flexbox/flexbox-main-page.ts index 283a8e07e..612fef82e 100644 --- a/apps/ui/src/flexbox/flexbox-main-page.ts +++ b/apps/ui/src/flexbox/flexbox-main-page.ts @@ -18,6 +18,7 @@ export function loadExamples() { examples.set('flex-perf', 'flexbox/flexbox-perf-comparison-page'); examples.set('flexbox-4143', 'flexbox/flexbox-4143-page'); examples.set('flexbox-4834', 'flexbox/flexbox-4834-page'); + examples.set("flexbox-ispassthroughparent", "flexbox/flexbox-ispassthroughparent-page"); return examples; } diff --git a/migrations.json b/migrations.json index f1929b173..d393949d2 100644 --- a/migrations.json +++ b/migrations.json @@ -1,109 +1,109 @@ { - "migrations": [ - { - "version": "10.1.0-beta.0", - "description": "Migrate .eslintrc files to use tsconfig with a wildcard", - "factory": "./src/migrations/update-10-1-0/migrate-eslintrc-tsconfig-wildcard", - "package": "@nrwl/workspace", - "name": "migrate-eslintrc-tsconfig-wildcard" - }, - { - "version": "10.3.0-beta.0", - "description": "Add @nrwl/cli as dependency", - "factory": "./src/migrations/update-10-3-0/add-cli-dependency", - "package": "@nrwl/workspace", - "name": "add-cli-dependency" - }, - { - "version": "10.3.0-beta.0", - "description": "Update typescript to v4", - "factory": "./src/migrations/update-10-3-0/update-typescript", - "package": "@nrwl/workspace", - "name": "update-10-3-0" - }, - { - "version": "10.3.0-beta.1", - "description": "Adds .vscode/extensions.json to a workspace", - "factory": "./src/migrations/update-10-3-0/add-vscode-extensions", - "package": "@nrwl/workspace", - "name": "add-vscode-extensions" - }, - { - "version": "10.3.0-beta.0", - "description": "Adds `buildableProjectDepsInPackageJsonType` for web and angular package builders", - "factory": "./src/migrations/update-10-3-0/add-buildable-project-deps-in-package-json-type", - "package": "@nrwl/workspace", - "name": "add-buildable-project-deps-in-package-json-type" - }, - { - "version": "10.1.0-beta.4", - "description": "Update jest to v26", - "factory": "./src/migrations/update-10-1-0/update-10-1-0", - "package": "@nrwl/jest", - "name": "update-10.1.0" - }, - { - "version": "10.2.0", - "description": "Remove deprecated jest builder options", - "factory": "./src/migrations/update-10-2-0/update-10-2-0", - "package": "@nrwl/jest", - "name": "update-10.2.0" - }, - { - "version": "10.3.0-beta.1", - "description": "Adds all jest projects into the root jest config", - "factory": "./src/migrations/update-10-3-0/update-projects-property", - "package": "@nrwl/jest", - "name": "update-projects-property" - }, - { - "version": "10.3.0-beta.1", - "description": "Update ts-jest to v26.4", - "factory": "./src/migrations/update-10-3-0/update-ts-jest", - "package": "@nrwl/jest", - "name": "update-ts-jest" - }, - { - "version": "10.3.0-beta.1", - "description": "Adds a jest extension to the recommended extensions for vscode", - "factory": "./src/migrations/update-10-3-0/add-jest-extension", - "package": "@nrwl/jest", - "name": "add-jest-extension" - }, - { - "version": "10.3.0-beta.1", - "description": "Update @typescript-eslint to v4.3", - "factory": "./src/migrations/update-10-3-0/update-10-3-0", - "package": "@nrwl/linter", - "name": "update-10.3.0" - }, - { - "version": "10.3.0-beta.0", - "description": "Migrate to the new ESLint builder and ESLint config style", - "factory": "./src/migrations/update-10-3-0/update-eslint-builder-and-config", - "package": "@nrwl/linter", - "name": "update-eslint-builder-and-config" - }, - { - "version": "10.3.0-beta.2", - "description": "Add explicit .json file extension to .eslintrc files, not using an extension is deprecated", - "factory": "./src/migrations/update-10-3-0/add-json-ext-to-eslintrc", - "package": "@nrwl/linter", - "name": "add-json-ext-to-eslintrc" - }, - { - "version": "10.3.0-beta.3", - "description": "Update implicitDependencies within nx.json to include root .eslintrc.json", - "factory": "./src/migrations/update-10-3-0/add-root-eslintrc-json-to-workspace-implicit-deps", - "package": "@nrwl/linter", - "name": "add-root-eslintrc-json-to-workspace-implicit-deps" - }, - { - "version": "10.1.0-beta.1", - "description": "Removes rootDir from node libs' tsconfig", - "factory": "./src/migrations/update-10-1-0/remove-root-dir", - "package": "@nrwl/node", - "name": "remove-root-dir" - } - ] -} \ No newline at end of file + "migrations": [ + { + "version": "10.1.0-beta.0", + "description": "Migrate .eslintrc files to use tsconfig with a wildcard", + "factory": "./src/migrations/update-10-1-0/migrate-eslintrc-tsconfig-wildcard", + "package": "@nrwl/workspace", + "name": "migrate-eslintrc-tsconfig-wildcard" + }, + { + "version": "10.3.0-beta.0", + "description": "Add @nrwl/cli as dependency", + "factory": "./src/migrations/update-10-3-0/add-cli-dependency", + "package": "@nrwl/workspace", + "name": "add-cli-dependency" + }, + { + "version": "10.3.0-beta.0", + "description": "Update typescript to v4", + "factory": "./src/migrations/update-10-3-0/update-typescript", + "package": "@nrwl/workspace", + "name": "update-10-3-0" + }, + { + "version": "10.3.0-beta.1", + "description": "Adds .vscode/extensions.json to a workspace", + "factory": "./src/migrations/update-10-3-0/add-vscode-extensions", + "package": "@nrwl/workspace", + "name": "add-vscode-extensions" + }, + { + "version": "10.3.0-beta.0", + "description": "Adds `buildableProjectDepsInPackageJsonType` for web and angular package builders", + "factory": "./src/migrations/update-10-3-0/add-buildable-project-deps-in-package-json-type", + "package": "@nrwl/workspace", + "name": "add-buildable-project-deps-in-package-json-type" + }, + { + "version": "10.1.0-beta.4", + "description": "Update jest to v26", + "factory": "./src/migrations/update-10-1-0/update-10-1-0", + "package": "@nrwl/jest", + "name": "update-10.1.0" + }, + { + "version": "10.2.0", + "description": "Remove deprecated jest builder options", + "factory": "./src/migrations/update-10-2-0/update-10-2-0", + "package": "@nrwl/jest", + "name": "update-10.2.0" + }, + { + "version": "10.3.0-beta.1", + "description": "Adds all jest projects into the root jest config", + "factory": "./src/migrations/update-10-3-0/update-projects-property", + "package": "@nrwl/jest", + "name": "update-projects-property" + }, + { + "version": "10.3.0-beta.1", + "description": "Update ts-jest to v26.4", + "factory": "./src/migrations/update-10-3-0/update-ts-jest", + "package": "@nrwl/jest", + "name": "update-ts-jest" + }, + { + "version": "10.3.0-beta.1", + "description": "Adds a jest extension to the recommended extensions for vscode", + "factory": "./src/migrations/update-10-3-0/add-jest-extension", + "package": "@nrwl/jest", + "name": "add-jest-extension" + }, + { + "version": "10.3.0-beta.1", + "description": "Update @typescript-eslint to v4.3", + "factory": "./src/migrations/update-10-3-0/update-10-3-0", + "package": "@nrwl/linter", + "name": "update-10.3.0" + }, + { + "version": "10.3.0-beta.0", + "description": "Migrate to the new ESLint builder and ESLint config style", + "factory": "./src/migrations/update-10-3-0/update-eslint-builder-and-config", + "package": "@nrwl/linter", + "name": "update-eslint-builder-and-config" + }, + { + "version": "10.3.0-beta.2", + "description": "Add explicit .json file extension to .eslintrc files, not using an extension is deprecated", + "factory": "./src/migrations/update-10-3-0/add-json-ext-to-eslintrc", + "package": "@nrwl/linter", + "name": "add-json-ext-to-eslintrc" + }, + { + "version": "10.3.0-beta.3", + "description": "Update implicitDependencies within nx.json to include root .eslintrc.json", + "factory": "./src/migrations/update-10-3-0/add-root-eslintrc-json-to-workspace-implicit-deps", + "package": "@nrwl/linter", + "name": "add-root-eslintrc-json-to-workspace-implicit-deps" + }, + { + "version": "10.1.0-beta.1", + "description": "Removes rootDir from node libs' tsconfig", + "factory": "./src/migrations/update-10-1-0/remove-root-dir", + "package": "@nrwl/node", + "name": "remove-root-dir" + } + ] +} diff --git a/package.json b/package.json index 846b7be65..7690b4a26 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "name": "nativescript", - "version": "7.1.3", + "version": "7.2.1", "license": "MIT", "config": { "npm_alias": "npm" }, "scripts": { - "setup": "npx rimraf hooks node_modules package-lock.json && $npm_package_config_npm_alias i && ts-patch install && npm run core:setup", + "clean": "git clean -f -X -d", + "setup": "npm run clean && $npm_package_config_npm_alias i && ts-patch install && npm run core:setup", "start": "nps", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", "clean": "rimraf -- hooks node_modules platforms package-lock.json webpack.config.js", @@ -68,6 +69,7 @@ "dotenv": "~8.2.0", "eslint": "~7.10.0", "eslint-config-prettier": "~6.11.0", + "eslint-plugin-prettier": "^3.3.1", "gonzales": "^1.0.7", "husky": "^4.2.5", "jest": "~26.2.2", @@ -75,7 +77,7 @@ "mocha": "^8.0.1", "mocha-typescript": "^1.1.17", "module-alias": "^2.2.2", - "nativescript": "~7.1.0", + "nativescript": "~7.2.0", "node-sass": "~4.14.1", "nps": "5.10.0", "parse-css": "git+https://github.com/tabatkins/parse-css.git", @@ -85,6 +87,7 @@ "rimraf": "3.0.2", "shady-css-parser": "^0.1.0", "terser-webpack-plugin": "~3.0.6", + "tree-kill": "^1.2.2", "ts-jest": "26.4.0", "ts-node": "~8.10.2", "ts-patch": "^1.3.1", diff --git a/packages/core/__tests__/observable/observable-array.ts b/packages/core/__tests__/observable/observable-array.ts new file mode 100644 index 000000000..8e2e5df06 --- /dev/null +++ b/packages/core/__tests__/observable/observable-array.ts @@ -0,0 +1,47 @@ +import { ObservableArray } from '@nativescript/core/data/observable-array'; +import { assert } from 'chai'; + +describe('observable-array', () => { + describe('splice', () => { + it('removes an item', () => { + const _array = new ObservableArray(); + + _array.push(1); + _array.push(2); + + _array.splice(0, 1); + + assert.equal(2, _array.getItem(0)); + }); + + it('replaces an item', () => { + const _array = new ObservableArray(); + + _array.push(1); + _array.push(2); + + _array.splice(0, 1, 3); + + assert.equal(3, _array.getItem(0)); + }); + + it('empties on start zero and no delete count', () => { + const _array = new ObservableArray(); + + _array.push(1); + + _array.splice(0); + assert.equal(0, _array.length); + }); + + it('empties on length set to zero', () => { + const _array = new ObservableArray(); + + _array.push(1); + _array.push(2); + + _array.length = 0; + assert.equal(0, _array.length); + }); + }); +}); diff --git a/packages/core/color/known-colors.ts b/packages/core/color/known-colors.ts index 766c3315e..470c68716 100644 --- a/packages/core/color/known-colors.ts +++ b/packages/core/color/known-colors.ts @@ -1,7 +1,7 @@ -const _allColors:{[k:string]:number} = {}; +const _allColors: { [k: string]: number } = {}; function registerColor(name: string | string[], value: number): number { if (Array.isArray(name)) { - name.forEach(n=>_allColors[n.toLowerCase()] = value) + name.forEach((n) => (_allColors[n.toLowerCase()] = value)); } else { _allColors[name.toLowerCase()] = value; } @@ -26,144 +26,144 @@ export function getKnownColor(name: string): number { } export const Transparent = registerColor('Transparent', 0x00000000); -export const AliceBlue = registerColor('AliceBlue', 0xffF0F8FF); -export const AntiqueWhite = registerColor('AntiqueWhite', 0xffFAEBD7); -export const Aqua = registerColor('Aqua', 0xff00FFFF); -export const Aquamarine = registerColor('Aquamarine', 0xff7FFFD4); -export const Azure = registerColor('Azure', 0xffF0FFFF); -export const Beige = registerColor('Beige', 0xffF5F5DC); -export const Bisque = registerColor('Bisque', 0xffFFE4C4); +export const AliceBlue = registerColor('AliceBlue', 0xfff0f8ff); +export const AntiqueWhite = registerColor('AntiqueWhite', 0xfffaebd7); +export const Aqua = registerColor('Aqua', 0xff00ffff); +export const Aquamarine = registerColor('Aquamarine', 0xff7fffd4); +export const Azure = registerColor('Azure', 0xfff0ffff); +export const Beige = registerColor('Beige', 0xfff5f5dc); +export const Bisque = registerColor('Bisque', 0xffffe4c4); export const Black = registerColor('Black', 0xff000000); -export const BlanchedAlmond = registerColor('BlanchedAlmond', 0xffFFEBCD); -export const Blue = registerColor('Blue', 0xff0000FF); -export const BlueViolet = registerColor('BlueViolet', 0xff8A2BE2); -export const Brown = registerColor('Brown', 0xffA52A2A); -export const BurlyWood = registerColor('BurlyWood', 0xffDEB887); -export const CadetBlue = registerColor('CadetBlue', 0xff5F9EA0); -export const Chartreuse = registerColor('Chartreuse', 0xff7FFF00); -export const Chocolate = registerColor('Chocolate', 0xffD2691E); -export const Coral = registerColor('Coral', 0xffFF7F50); -export const CornflowerBlue = registerColor('CornflowerBlue', 0xff6495ED); -export const Cornsilk = registerColor('Cornsilk', 0xffFFF8DC); -export const Crimson = registerColor('Crimson', 0xffDC143C); -export const Cyan = registerColor('Cyan', 0xff00FFFF); -export const DarkBlue = registerColor('DarkBlue', 0xff00008B); -export const DarkCyan = registerColor('DarkCyan', 0xff008B8B); -export const DarkGoldenRod = registerColor('DarkGoldenRod', 0xffB8860B); -export const DarkGray = registerColor(['DarkGray', 'DarkGrey'], 0xffA9A9A9); +export const BlanchedAlmond = registerColor('BlanchedAlmond', 0xffffebcd); +export const Blue = registerColor('Blue', 0xff0000ff); +export const BlueViolet = registerColor('BlueViolet', 0xff8a2be2); +export const Brown = registerColor('Brown', 0xffa52a2a); +export const BurlyWood = registerColor('BurlyWood', 0xffdeb887); +export const CadetBlue = registerColor('CadetBlue', 0xff5f9ea0); +export const Chartreuse = registerColor('Chartreuse', 0xff7fff00); +export const Chocolate = registerColor('Chocolate', 0xffd2691e); +export const Coral = registerColor('Coral', 0xffff7f50); +export const CornflowerBlue = registerColor('CornflowerBlue', 0xff6495ed); +export const Cornsilk = registerColor('Cornsilk', 0xfffff8dc); +export const Crimson = registerColor('Crimson', 0xffdc143c); +export const Cyan = registerColor('Cyan', 0xff00ffff); +export const DarkBlue = registerColor('DarkBlue', 0xff00008b); +export const DarkCyan = registerColor('DarkCyan', 0xff008b8b); +export const DarkGoldenRod = registerColor('DarkGoldenRod', 0xffb8860b); +export const DarkGray = registerColor(['DarkGray', 'DarkGrey'], 0xffa9a9a9); export const DarkGreen = registerColor('DarkGreen', 0xff006400); -export const DarkKhaki = registerColor('DarkKhaki', 0xffBDB76B); -export const DarkMagenta = registerColor('DarkMagenta', 0xff8B008B); -export const DarkOliveGreen = registerColor('DarkOliveGreen', 0xff556B2F); -export const DarkOrange = registerColor('DarkOrange', 0xffFF8C00); -export const DarkOrchid = registerColor('DarkOrchid', 0xff9932CC); -export const DarkRed = registerColor('DarkRed', 0xff8B0000); -export const DarkSalmon = registerColor('DarkSalmon', 0xffE9967A); -export const DarkSeaGreen = registerColor('DarkSeaGreen', 0xff8FBC8F); -export const DarkSlateBlue = registerColor('DarkSlateBlue', 0xff483D8B); -export const DarkSlateGray = registerColor(['DarkSlateGray', 'DarkSlateGrey'], 0xff2F4F4F); -export const DarkTurquoise = registerColor('DarkTurquoise', 0xff00CED1); -export const DarkViolet = registerColor('DarkViolet', 0xff9400D3); -export const DeepPink = registerColor('DeepPink', 0xffFF1493); -export const DeepSkyBlue = registerColor('DeepSkyBlue', 0xff00BFFF); +export const DarkKhaki = registerColor('DarkKhaki', 0xffbdb76b); +export const DarkMagenta = registerColor('DarkMagenta', 0xff8b008b); +export const DarkOliveGreen = registerColor('DarkOliveGreen', 0xff556b2f); +export const DarkOrange = registerColor('DarkOrange', 0xffff8c00); +export const DarkOrchid = registerColor('DarkOrchid', 0xff9932cc); +export const DarkRed = registerColor('DarkRed', 0xff8b0000); +export const DarkSalmon = registerColor('DarkSalmon', 0xffe9967a); +export const DarkSeaGreen = registerColor('DarkSeaGreen', 0xff8fbc8f); +export const DarkSlateBlue = registerColor('DarkSlateBlue', 0xff483d8b); +export const DarkSlateGray = registerColor(['DarkSlateGray', 'DarkSlateGrey'], 0xff2f4f4f); +export const DarkTurquoise = registerColor('DarkTurquoise', 0xff00ced1); +export const DarkViolet = registerColor('DarkViolet', 0xff9400d3); +export const DeepPink = registerColor('DeepPink', 0xffff1493); +export const DeepSkyBlue = registerColor('DeepSkyBlue', 0xff00bfff); export const DimGray = registerColor(['DimGray', 'DimGrey'], 0xff696969); -export const DodgerBlue = registerColor('DodgerBlue', 0xff1E90FF); -export const FireBrick = registerColor('FireBrick', 0xffB22222); -export const FloralWhite = registerColor('FloralWhite', 0xffFFFAF0); -export const ForestGreen = registerColor('ForestGreen', 0xff228B22); -export const Fuchsia = registerColor('Fuchsia', 0xffFF00FF); -export const Gainsboro = registerColor('Gainsboro', 0xffDCDCDC); -export const GhostWhite = registerColor('GhostWhite', 0xffF8F8FF); -export const Gold = registerColor('Gold', 0xffFFD700); -export const GoldenRod = registerColor('GoldenRod', 0xffDAA520); +export const DodgerBlue = registerColor('DodgerBlue', 0xff1e90ff); +export const FireBrick = registerColor('FireBrick', 0xffb22222); +export const FloralWhite = registerColor('FloralWhite', 0xfffffaf0); +export const ForestGreen = registerColor('ForestGreen', 0xff228b22); +export const Fuchsia = registerColor('Fuchsia', 0xffff00ff); +export const Gainsboro = registerColor('Gainsboro', 0xffdcdcdc); +export const GhostWhite = registerColor('GhostWhite', 0xfff8f8ff); +export const Gold = registerColor('Gold', 0xffffd700); +export const GoldenRod = registerColor('GoldenRod', 0xffdaa520); export const Gray = registerColor(['Gray', 'Grey'], 0xff808080); export const Green = registerColor('Green', 0xff008000); -export const GreenYellow = registerColor('GreenYellow', 0xffADFF2F); -export const HoneyDew = registerColor('HoneyDew', 0xffF0FFF0); -export const HotPink = registerColor('HotPink', 0xffFF69B4); -export const IndianRed = registerColor('IndianRed', 0xffCD5C5C); -export const Indigo = registerColor('Indigo', 0xff4B0082); -export const Ivory = registerColor('Ivory', 0xffFFFFF0); -export const Khaki = registerColor('Khaki', 0xffF0E68C); -export const Lavender = registerColor('Lavender', 0xffE6E6FA); -export const LavenderBlush = registerColor('LavenderBlush', 0xffFFF0F5); -export const LawnGreen = registerColor('LawnGreen', 0xff7CFC00); -export const LemonChiffon = registerColor('LemonChiffon', 0xffFFFACD); -export const LightBlue = registerColor('LightBlue', 0xffADD8E6); -export const LightCoral = registerColor('LightCoral', 0xffF08080); -export const LightCyan = registerColor('LightCyan', 0xffE0FFFF); -export const LightGoldenRodYellow = registerColor('LightGoldenRodYellow', 0xffFAFAD2); -export const LightGray = registerColor(['LightGray', 'LightGrey'], 0xffD3D3D3); -export const LightGreen = registerColor('LightGreen', 0xff90EE90); -export const LightPink = registerColor('LightPink', 0xffFFB6C1); -export const LightSalmon = registerColor('LightSalmon', 0xffFFA07A); -export const LightSeaGreen = registerColor('LightSeaGreen', 0xff20B2AA); -export const LightSkyBlue = registerColor('LightSkyBlue', 0xff87CEFA); +export const GreenYellow = registerColor('GreenYellow', 0xffadff2f); +export const HoneyDew = registerColor('HoneyDew', 0xfff0fff0); +export const HotPink = registerColor('HotPink', 0xffff69b4); +export const IndianRed = registerColor('IndianRed', 0xffcd5c5c); +export const Indigo = registerColor('Indigo', 0xff4b0082); +export const Ivory = registerColor('Ivory', 0xfffffff0); +export const Khaki = registerColor('Khaki', 0xfff0e68c); +export const Lavender = registerColor('Lavender', 0xffe6e6fa); +export const LavenderBlush = registerColor('LavenderBlush', 0xfffff0f5); +export const LawnGreen = registerColor('LawnGreen', 0xff7cfc00); +export const LemonChiffon = registerColor('LemonChiffon', 0xfffffacd); +export const LightBlue = registerColor('LightBlue', 0xffadd8e6); +export const LightCoral = registerColor('LightCoral', 0xfff08080); +export const LightCyan = registerColor('LightCyan', 0xffe0ffff); +export const LightGoldenRodYellow = registerColor('LightGoldenRodYellow', 0xfffafad2); +export const LightGray = registerColor(['LightGray', 'LightGrey'], 0xffd3d3d3); +export const LightGreen = registerColor('LightGreen', 0xff90ee90); +export const LightPink = registerColor('LightPink', 0xffffb6c1); +export const LightSalmon = registerColor('LightSalmon', 0xffffa07a); +export const LightSeaGreen = registerColor('LightSeaGreen', 0xff20b2aa); +export const LightSkyBlue = registerColor('LightSkyBlue', 0xff87cefa); export const LightSlateGray = registerColor(['LightSlateGray', 'LightSlateGrey'], 0xff778899); -export const LightSteelBlue = registerColor('LightSteelBlue', 0xffB0C4DE); -export const LightYellow = registerColor('LightYellow', 0xffFFFFE0); -export const Lime = registerColor('Lime', 0xff00FF00); -export const LimeGreen = registerColor('LimeGreen', 0xff32CD32); -export const Linen = registerColor('Linen', 0xffFAF0E6); -export const Magenta = registerColor('Magenta', 0xffFF00FF); +export const LightSteelBlue = registerColor('LightSteelBlue', 0xffb0c4de); +export const LightYellow = registerColor('LightYellow', 0xffffffe0); +export const Lime = registerColor('Lime', 0xff00ff00); +export const LimeGreen = registerColor('LimeGreen', 0xff32cd32); +export const Linen = registerColor('Linen', 0xfffaf0e6); +export const Magenta = registerColor('Magenta', 0xffff00ff); export const Maroon = registerColor('Maroon', 0xff800000); -export const MediumAquaMarine = registerColor('MediumAquaMarine', 0xff66CDAA); -export const MediumBlue = registerColor('MediumBlue', 0xff0000CD); -export const MediumOrchid = registerColor('MediumOrchid', 0xffBA55D3); -export const MediumPurple = registerColor('MediumPurple', 0xff9370DB); -export const MediumSeaGreen = registerColor('MediumSeaGreen', 0xff3CB371); -export const MediumSlateBlue = registerColor('MediumSlateBlue', 0xff7B68EE); -export const MediumSpringGreen = registerColor('MediumSpringGreen', 0xff00FA9A); -export const MediumTurquoise = registerColor('MediumTurquoise', 0xff48D1CC); -export const MediumVioletRed = registerColor('MediumVioletRed', 0xffC71585); +export const MediumAquaMarine = registerColor('MediumAquaMarine', 0xff66cdaa); +export const MediumBlue = registerColor('MediumBlue', 0xff0000cd); +export const MediumOrchid = registerColor('MediumOrchid', 0xffba55d3); +export const MediumPurple = registerColor('MediumPurple', 0xff9370db); +export const MediumSeaGreen = registerColor('MediumSeaGreen', 0xff3cb371); +export const MediumSlateBlue = registerColor('MediumSlateBlue', 0xff7b68ee); +export const MediumSpringGreen = registerColor('MediumSpringGreen', 0xff00fa9a); +export const MediumTurquoise = registerColor('MediumTurquoise', 0xff48d1cc); +export const MediumVioletRed = registerColor('MediumVioletRed', 0xffc71585); export const MidnightBlue = registerColor('MidnightBlue', 0xff191970); -export const MintCream = registerColor('MintCream', 0xffF5FFFA); -export const MistyRose = registerColor('MistyRose', 0xffFFE4E1); -export const Moccasin = registerColor('Moccasin', 0xffFFE4B5); -export const NavajoWhite = registerColor('NavajoWhite', 0xffFFDEAD); +export const MintCream = registerColor('MintCream', 0xfff5fffa); +export const MistyRose = registerColor('MistyRose', 0xffffe4e1); +export const Moccasin = registerColor('Moccasin', 0xffffe4b5); +export const NavajoWhite = registerColor('NavajoWhite', 0xffffdead); export const Navy = registerColor('Navy', 0xff000080); -export const OldLace = registerColor('OldLace', 0xffFDF5E6); +export const OldLace = registerColor('OldLace', 0xfffdf5e6); export const Olive = registerColor('Olive', 0xff808000); -export const OliveDrab = registerColor('OliveDrab', 0xff6B8E23); -export const Orange = registerColor('Orange', 0xffFFA500); -export const OrangeRed = registerColor('OrangeRed', 0xffFF4500); -export const Orchid = registerColor('Orchid', 0xffDA70D6); -export const PaleGoldenRod = registerColor('PaleGoldenRod', 0xffEEE8AA); -export const PaleGreen = registerColor('PaleGreen', 0xff98FB98); -export const PaleTurquoise = registerColor('PaleTurquoise', 0xffAFEEEE); -export const PaleVioletRed = registerColor('PaleVioletRed', 0xffDB7093); -export const PapayaWhip = registerColor('PapayaWhip', 0xffFFEFD5); -export const PeachPuff = registerColor('PeachPuff', 0xffFFDAB9); -export const Peru = registerColor('Peru', 0xffCD853F); -export const Pink = registerColor('Pink', 0xffFFC0CB); -export const Plum = registerColor('Plum', 0xffDDA0DD); -export const PowderBlue = registerColor('PowderBlue', 0xffB0E0E6); +export const OliveDrab = registerColor('OliveDrab', 0xff6b8e23); +export const Orange = registerColor('Orange', 0xffffa500); +export const OrangeRed = registerColor('OrangeRed', 0xffff4500); +export const Orchid = registerColor('Orchid', 0xffda70d6); +export const PaleGoldenRod = registerColor('PaleGoldenRod', 0xffeee8aa); +export const PaleGreen = registerColor('PaleGreen', 0xff98fb98); +export const PaleTurquoise = registerColor('PaleTurquoise', 0xffafeeee); +export const PaleVioletRed = registerColor('PaleVioletRed', 0xffdb7093); +export const PapayaWhip = registerColor('PapayaWhip', 0xffffefd5); +export const PeachPuff = registerColor('PeachPuff', 0xffffdab9); +export const Peru = registerColor('Peru', 0xffcd853f); +export const Pink = registerColor('Pink', 0xffffc0cb); +export const Plum = registerColor('Plum', 0xffdda0dd); +export const PowderBlue = registerColor('PowderBlue', 0xffb0e0e6); export const Purple = registerColor('Purple', 0xff800080); export const RebeccaPurple = registerColor('RebeccaPurple', 0xff663399); -export const Red = registerColor('Red', 0xffFF0000); -export const RosyBrown = registerColor('RosyBrown', 0xffBC8F8F); -export const RoyalBlue = registerColor('RoyalBlue', 0xff4169E1); -export const SaddleBrown = registerColor('SaddleBrown', 0xff8B4513); -export const Salmon = registerColor('Salmon', 0xffFA8072); -export const SandyBrown = registerColor('SandyBrown', 0xffF4A460); -export const SeaGreen = registerColor('SeaGreen', 0xff2E8B57); -export const SeaShell = registerColor('SeaShell', 0xffFFF5EE); -export const Sienna = registerColor('Sienna', 0xffA0522D); -export const Silver = registerColor('Silver', 0xffC0C0C0); -export const SkyBlue = registerColor('SkyBlue', 0xff87CEEB); -export const SlateBlue = registerColor('SlateBlue', 0xff6A5ACD); +export const Red = registerColor('Red', 0xffff0000); +export const RosyBrown = registerColor('RosyBrown', 0xffbc8f8f); +export const RoyalBlue = registerColor('RoyalBlue', 0xff4169e1); +export const SaddleBrown = registerColor('SaddleBrown', 0xff8b4513); +export const Salmon = registerColor('Salmon', 0xfffa8072); +export const SandyBrown = registerColor('SandyBrown', 0xfff4a460); +export const SeaGreen = registerColor('SeaGreen', 0xff2e8b57); +export const SeaShell = registerColor('SeaShell', 0xfffff5ee); +export const Sienna = registerColor('Sienna', 0xffa0522d); +export const Silver = registerColor('Silver', 0xffc0c0c0); +export const SkyBlue = registerColor('SkyBlue', 0xff87ceeb); +export const SlateBlue = registerColor('SlateBlue', 0xff6a5acd); export const SlateGray = registerColor(['SlateGray', 'SlateGrey'], 0xff708090); -export const Snow = registerColor('Snow', 0xffFFFAFA); -export const SpringGreen = registerColor('SpringGreen', 0xff00FF7F); -export const SteelBlue = registerColor('SteelBlue', 0xff4682B4); -export const Tan = registerColor('Tan', 0xffD2B48C); +export const Snow = registerColor('Snow', 0xfffffafa); +export const SpringGreen = registerColor('SpringGreen', 0xff00ff7f); +export const SteelBlue = registerColor('SteelBlue', 0xff4682b4); +export const Tan = registerColor('Tan', 0xffd2b48c); export const Teal = registerColor('Teal', 0xff008080); -export const Thistle = registerColor('Thistle', 0xffD8BFD8); -export const Tomato = registerColor('Tomato', 0xffFF6347); -export const Turquoise = registerColor('Turquoise', 0xff40E0D0); -export const Violet = registerColor('Violet', 0xffEE82EE); -export const Wheat = registerColor('Wheat', 0xffF5DEB3); -export const White = registerColor('White', 0xffFFFFFF); -export const WhiteSmoke = registerColor('WhiteSmoke', 0xffF5F5F5); -export const Yellow = registerColor('Yellow', 0xffFFFF00); -export const YellowGreen = registerColor('YellowGreen', 0xff9ACD32); +export const Thistle = registerColor('Thistle', 0xffd8bfd8); +export const Tomato = registerColor('Tomato', 0xffff6347); +export const Turquoise = registerColor('Turquoise', 0xff40e0d0); +export const Violet = registerColor('Violet', 0xffee82ee); +export const Wheat = registerColor('Wheat', 0xfff5deb3); +export const White = registerColor('White', 0xffffffff); +export const WhiteSmoke = registerColor('WhiteSmoke', 0xfff5f5f5); +export const Yellow = registerColor('Yellow', 0xffffff00); +export const YellowGreen = registerColor('YellowGreen', 0xff9acd32); diff --git a/packages/core/data/observable-array/index.ts b/packages/core/data/observable-array/index.ts index beba6eeee..5dafad024 100644 --- a/packages/core/data/observable-array/index.ts +++ b/packages/core/data/observable-array/index.ts @@ -33,7 +33,6 @@ export interface ChangedData extends EventData { * Number of added items. */ addedCount: number; - } const CHANGE = 'change'; @@ -116,8 +115,8 @@ export class ObservableArray extends Observable { set length(value: number) { if (types.isNumber(value) && this._array && this._array.length !== value) { - const added=[]; - for (let i=this._array.length;i < value;++i) { + const added = []; + for (let i = this._array.length; i < value; ++i) { added.push(undefined); } this.splice(value, this._array.length - value, ...added); @@ -247,7 +246,7 @@ export class ObservableArray extends Observable { */ splice(start: number, deleteCount?: number, ...items: any): T[] { const length = this._array.length; - const result = this._array.splice(start, deleteCount, ...items); + const result = arguments.length === 1 ? this._array.splice(start) : this._array.splice(start, deleteCount, ...items); this.notify(>{ eventName: CHANGE, diff --git a/packages/core/data/observable/index.d.ts b/packages/core/data/observable/index.d.ts index 61366b1b6..f5e9f49cd 100644 --- a/packages/core/data/observable/index.d.ts +++ b/packages/core/data/observable/index.d.ts @@ -12,13 +12,11 @@ export interface EventData { object: Observable; } - export interface NotifyData extends Partial { eventName: string; object?: Observable; } - /** * Data for the "propertyChange" event. */ diff --git a/packages/core/global-types.d.ts b/packages/core/global-types.d.ts index dca8632b2..c67f58f95 100644 --- a/packages/core/global-types.d.ts +++ b/packages/core/global-types.d.ts @@ -152,13 +152,6 @@ interface ModuleContext { path: string; } -// Define a minimal subset of NodeRequire and NodeModule so user apps can compile without -// installing @types/node - -interface NodeRequire { - (id: string): any; -} - interface NodeModule { exports: any; id: string; @@ -221,12 +214,8 @@ interface RequireContext { resolve(id: string): string; } -interface NodeRequire { - context(path: string, deep?: boolean, filter?: RegExp): RequireContext; -} - -declare let __dirname: string; -declare let __filename: string; +declare var __dirname: string; +declare var __filename: string; declare let module: NodeModule; // Same as module.exports diff --git a/packages/core/image-source/index.ios.ts b/packages/core/image-source/index.ios.ts index e829a1408..fd5782037 100644 --- a/packages/core/image-source/index.ios.ts +++ b/packages/core/image-source/index.ios.ts @@ -7,7 +7,7 @@ import { Color } from '../color'; // Types. import { path as fsPath, knownFolders } from '../file-system'; -import { isFileOrResourcePath, RESOURCE_PREFIX, layout } from '../utils'; +import { isFileOrResourcePath, RESOURCE_PREFIX, layout, releaseNativeObject } from '../utils'; import { getScaledDimensions } from './image-source-common'; diff --git a/packages/core/module-name-resolver/non-bundle-workflow-compat.ts b/packages/core/module-name-resolver/non-bundle-workflow-compat.ts index 1c205f84a..cd9e881a2 100644 --- a/packages/core/module-name-resolver/non-bundle-workflow-compat.ts +++ b/packages/core/module-name-resolver/non-bundle-workflow-compat.ts @@ -25,7 +25,7 @@ function processFile(file: fs.File) { const loadContent = () => file.readTextSync(); switch (file.extension.toLocaleLowerCase()) { - case '.js':{ + case '.js': { const noExtPath = filePathRelativeToApp.substr(0, filePathRelativeToApp.length - '.js'.length); register(filePathRelativeToApp, function () { diff --git a/packages/core/package.json b/packages/core/package.json index 7a504224f..1fa87139c 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -3,7 +3,7 @@ "main": "index", "types": "index.d.ts", "description": "NativeScript Core Modules", - "version": "7.1.3", + "version": "7.2.1", "homepage": "https://nativescript.org", "repository": { "type": "git", diff --git a/packages/core/platforms/android/widgets-release.aar b/packages/core/platforms/android/widgets-release.aar index 30ac9b12e..0bbd9fa3d 100644 Binary files a/packages/core/platforms/android/widgets-release.aar and b/packages/core/platforms/android/widgets-release.aar differ diff --git a/packages/core/platforms/ios/TNSWidgets.framework.dSYM.zip b/packages/core/platforms/ios/TNSWidgets.framework.dSYM.zip deleted file mode 100644 index c3de7d45f..000000000 Binary files a/packages/core/platforms/ios/TNSWidgets.framework.dSYM.zip and /dev/null differ diff --git a/packages/core/platforms/ios/TNSWidgets.framework/TNSWidgets b/packages/core/platforms/ios/TNSWidgets.framework/TNSWidgets deleted file mode 100755 index b2b829867..000000000 Binary files a/packages/core/platforms/ios/TNSWidgets.framework/TNSWidgets and /dev/null differ diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/Info.plist b/packages/core/platforms/ios/TNSWidgets.xcframework/Info.plist new file mode 100644 index 000000000..953413568 --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/Info.plist @@ -0,0 +1,44 @@ + + + + + AvailableLibraries + + + DebugSymbolsPath + dSYMs + LibraryIdentifier + ios-arm64 + LibraryPath + TNSWidgets.framework + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + DebugSymbolsPath + dSYMs + LibraryIdentifier + ios-arm64_x86_64-simulator + LibraryPath + TNSWidgets.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + ios + SupportedPlatformVariant + simulator + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/packages/core/platforms/ios/TNSWidgets.framework/Headers/NSData+Async.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/NSData+Async.h similarity index 90% rename from packages/core/platforms/ios/TNSWidgets.framework/Headers/NSData+Async.h rename to packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/NSData+Async.h index 36508cc54..3e0cc8207 100644 --- a/packages/core/platforms/ios/TNSWidgets.framework/Headers/NSData+Async.h +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/NSData+Async.h @@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)writeToFile:(nonnull NSString*) path atomically:(BOOL)atomically - completion:(void (^) ())callback; + completion:(void (^) (void))callback; @end diff --git a/packages/core/platforms/ios/TNSWidgets.framework/Headers/NSString+Async.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/NSString+Async.h similarity index 100% rename from packages/core/platforms/ios/TNSWidgets.framework/Headers/NSString+Async.h rename to packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/NSString+Async.h diff --git a/packages/core/platforms/ios/TNSWidgets.framework/Headers/TNSLabel.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/TNSLabel.h similarity index 100% rename from packages/core/platforms/ios/TNSWidgets.framework/Headers/TNSLabel.h rename to packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/TNSLabel.h diff --git a/packages/core/platforms/ios/TNSWidgets.framework/Headers/TNSProcess.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/TNSProcess.h similarity index 96% rename from packages/core/platforms/ios/TNSWidgets.framework/Headers/TNSProcess.h rename to packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/TNSProcess.h index baea95509..d2f657014 100644 --- a/packages/core/platforms/ios/TNSWidgets.framework/Headers/TNSProcess.h +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/TNSProcess.h @@ -14,7 +14,7 @@ /** * Get the milliseconds since the process started. */ -double __tns_uptime(); +double __tns_uptime(void); /** * Provides access to NSLog. The runtime implementation of console.log is filtered in release. diff --git a/packages/core/platforms/ios/TNSWidgets.framework/Headers/TNSWidgets.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/TNSWidgets.h similarity index 100% rename from packages/core/platforms/ios/TNSWidgets.framework/Headers/TNSWidgets.h rename to packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/TNSWidgets.h diff --git a/packages/core/platforms/ios/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h similarity index 100% rename from packages/core/platforms/ios/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h rename to packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h diff --git a/packages/core/platforms/ios/TNSWidgets.framework/Headers/UIView+PassThroughParent.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/UIView+PassThroughParent.h similarity index 100% rename from packages/core/platforms/ios/TNSWidgets.framework/Headers/UIView+PassThroughParent.h rename to packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/UIView+PassThroughParent.h diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Info.plist b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Info.plist new file mode 100644 index 000000000..a88b73581 Binary files /dev/null and b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Info.plist differ diff --git a/packages/core/platforms/ios/TNSWidgets.framework/Modules/module.modulemap b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Modules/module.modulemap similarity index 100% rename from packages/core/platforms/ios/TNSWidgets.framework/Modules/module.modulemap rename to packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Modules/module.modulemap diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h new file mode 100644 index 000000000..d3d71a88f --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h @@ -0,0 +1,17 @@ +// +// NSObject+Swizzling.h +// TNSWidgets +// +// Created by Manol Donev on 21.08.18. +// Copyright © 2018 Telerik A D. All rights reserved. +// + +#import +#import + + +@interface NSObject (Swizzling) + ++ (void)swizzleInstanceMethodWithOriginalSelector:(SEL)originalSelector fromClass:(Class)classContainigOriginalSel withSwizzlingSelector:(SEL)swizzlingSelector; + +@end diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h new file mode 100644 index 000000000..65ccdf02d --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h @@ -0,0 +1,18 @@ +// +// UIView+PropertyBag.h +// TNSWidgets +// +// Created by Manol Donev on 21.08.18. +// Copyright © 2018 Telerik A D. All rights reserved. +// + +#import +#import + + +@interface UIView (PropertyBag) + +- (id) propertyValueForKey:(NSString*) key; +- (void) setPropertyValue:(id) value forKey:(NSString*) key; + +@end diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/TNSWidgets b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/TNSWidgets new file mode 100755 index 000000000..6078a3943 Binary files /dev/null and b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/TNSWidgets differ diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist new file mode 100644 index 000000000..ef076e371 --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.org.nativescript.TNSWidgets + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets new file mode 100644 index 000000000..28407f0a9 Binary files /dev/null and b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets differ diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSData+Async.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSData+Async.h new file mode 100644 index 000000000..3e0cc8207 --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSData+Async.h @@ -0,0 +1,24 @@ +// +// NSData+Async.h +// TNSWidgets +// +// Created by Peter Staev on 7.08.19. +// Copyright © 2019 Telerik A D. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSData (Async) + ++ (void)dataWithContentsOfFile:(nonnull NSString*)path + completion:(void (^) (NSData*))callback; + +- (void)writeToFile:(nonnull NSString*) path + atomically:(BOOL)atomically + completion:(void (^) (void))callback; + +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSString+Async.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSString+Async.h new file mode 100644 index 000000000..2f0592262 --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSString+Async.h @@ -0,0 +1,25 @@ +// +// NSString+Async.h +// TNSWidgets +// +// Created by Peter Staev on 5.08.19. +// Copyright © 2019 Telerik A D. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSString (Async) + ++ (void)stringWithContentsOfFile:(nonnull NSString*)path + encoding:(NSStringEncoding)enc + completion:(void (^) (NSString*, NSError*))callback; + +- (void)writeToFile:(nonnull NSString*) path + atomically:(BOOL)atomically + encoding:(NSStringEncoding)enc + completion:(void (^) (NSError*))callback; +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSLabel.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSLabel.h new file mode 100644 index 000000000..1c170b9c9 --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSLabel.h @@ -0,0 +1,16 @@ +// +// TNSLabel.h +// TNSWidgets +// +// Created by Hristo Hristov on 6/9/16. +// Copyright © 2016 Telerik A D. All rights reserved. +// + +#import + +@interface TNSLabel : UILabel + +@property(nonatomic) UIEdgeInsets padding; +@property(nonatomic) UIEdgeInsets borderThickness; + +@end diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSProcess.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSProcess.h new file mode 100644 index 000000000..d2f657014 --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSProcess.h @@ -0,0 +1,29 @@ +// +// TNSProcess.h +// TNSWidgets +// +// Created by Panayot Cankov on 15/05/2017. +// Copyright © 2017 Telerik A D. All rights reserved. +// + +#ifndef TNSProcess_h +#define TNSProcess_h + +#import + +/** + * Get the milliseconds since the process started. + */ +double __tns_uptime(void); + +/** + * Provides access to NSLog. The runtime implementation of console.log is filtered in release. + * We rarely need to log in release but in cases such as when logging app startup times in release, + * this will be convenient shortcut to NSLog, NSLog is not exposed. + * + * Please note the {N} CLI may be filtering app output, prefixing the message with "CONSOLE LOG" + * will make the logs visible in "tns run ios --release" builds. + */ +void __nslog(NSString* message); + +#endif /* TNSProcess_h */ diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSWidgets.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSWidgets.h new file mode 100644 index 000000000..7da1d2adb --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSWidgets.h @@ -0,0 +1,24 @@ +// +// TNSWidgets.h +// TNSWidgets +// +// Created by Panayot Cankov on 4/27/16. +// Copyright © 2016 Telerik A D. All rights reserved. +// + +#import + +//! Project version number for TNSWidgets. +FOUNDATION_EXPORT double TNSWidgetsVersionNumber; + +//! Project version string for TNSWidgets. +FOUNDATION_EXPORT const unsigned char TNSWidgetsVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#import "UIImage+TNSBlocks.h" +#import "UIView+PassThroughParent.h" +#import "TNSLabel.h" +#import "TNSProcess.h" +#import "NSString+Async.h" +#import "NSData+Async.h" diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h new file mode 100644 index 000000000..9e67228be --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h @@ -0,0 +1,26 @@ +// +// UIImage+UIImage_Async.h +// TKImageAsync +// +// Created by Panayot Cankov on 4/18/16. +// Copyright © 2016 Telerik A D. All rights reserved. +// + +@interface UIImage (TNSBlocks) + +/** + * Similar to imageNamed: however it runs on a separate queue so the UI thread is not blocked. + * It also draws the UIImage in a small thumb to force decoding potentially avoiding UI hicckups when displayed. + */ ++ (void) tns_safeDecodeImageNamed: (NSString*) name completion: (void (^) (UIImage*))callback; + +/** + * Same as imageNamed, however calls to this method are sinchronized to be thread safe in iOS8 along with calls to tns_safeImageNamed and tns_safeDecodeImageNamed:completion: + * imageNamed is thread safe in iOS 9 and later so in later versions this methods simply fallbacks to imageNamed: + */ ++ (UIImage*) tns_safeImageNamed: (NSString*) name; + ++ (void) tns_decodeImageWithData: (NSData*) data completion: (void (^) (UIImage*))callback; ++ (void) tns_decodeImageWidthContentsOfFile: (NSString*) file completion: (void (^) (UIImage*))callback; + +@end diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIView+PassThroughParent.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIView+PassThroughParent.h new file mode 100644 index 000000000..e5f68c568 --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIView+PassThroughParent.h @@ -0,0 +1,17 @@ +// +// UIView+PassThroughParent.h +// TNSWidgets +// +// Created by Manol Donev on 21.08.18. +// Copyright © 2018 Telerik A D. All rights reserved. +// + +#import + + +@interface UIView (PassThroughParent) + +- (BOOL) passThroughParent; +- (void) setPassThroughParent:(BOOL) passThroughParent; + +@end diff --git a/packages/core/platforms/ios/TNSWidgets.framework/Info.plist b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Info.plist similarity index 52% rename from packages/core/platforms/ios/TNSWidgets.framework/Info.plist rename to packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Info.plist index ab32e047d..2ebc3f8ac 100644 Binary files a/packages/core/platforms/ios/TNSWidgets.framework/Info.plist and b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Info.plist differ diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Modules/module.modulemap b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Modules/module.modulemap new file mode 100644 index 000000000..9184cde23 --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module TNSWidgets { + umbrella header "TNSWidgets.h" + + export * + module * { export * } +} diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h new file mode 100644 index 000000000..d3d71a88f --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h @@ -0,0 +1,17 @@ +// +// NSObject+Swizzling.h +// TNSWidgets +// +// Created by Manol Donev on 21.08.18. +// Copyright © 2018 Telerik A D. All rights reserved. +// + +#import +#import + + +@interface NSObject (Swizzling) + ++ (void)swizzleInstanceMethodWithOriginalSelector:(SEL)originalSelector fromClass:(Class)classContainigOriginalSel withSwizzlingSelector:(SEL)swizzlingSelector; + +@end diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h new file mode 100644 index 000000000..65ccdf02d --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h @@ -0,0 +1,18 @@ +// +// UIView+PropertyBag.h +// TNSWidgets +// +// Created by Manol Donev on 21.08.18. +// Copyright © 2018 Telerik A D. All rights reserved. +// + +#import +#import + + +@interface UIView (PropertyBag) + +- (id) propertyValueForKey:(NSString*) key; +- (void) setPropertyValue:(id) value forKey:(NSString*) key; + +@end diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/TNSWidgets b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/TNSWidgets new file mode 100755 index 000000000..3c467383e Binary files /dev/null and b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/TNSWidgets differ diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/_CodeSignature/CodeResources b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/_CodeSignature/CodeResources new file mode 100644 index 000000000..c987e1c62 --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/_CodeSignature/CodeResources @@ -0,0 +1,212 @@ + + + + + files + + Headers/NSData+Async.h + + 9BsuK8QsA57YnHHgpWIgaHygSEk= + + Headers/NSString+Async.h + + o8366y9zYMOVyObC3vtKKy/8jxA= + + Headers/TNSLabel.h + + x8V4jT6oNNls+KE3y/DE6ij9eCk= + + Headers/TNSProcess.h + + dHuocpQ4b8KDApobwYNCqXcC6ZE= + + Headers/TNSWidgets.h + + gUvu5bjZg5Aie5iJ1krxFmDrHwk= + + Headers/UIImage+TNSBlocks.h + + OzGlvoGOJcFC6Z+YR5xThjLTUK4= + + Headers/UIView+PassThroughParent.h + + zdxBV/QJg7NPyx04RmZrXsxbHKU= + + Info.plist + + ADh4pPlA/MlPeoqmSDibKmrOKb0= + + Modules/module.modulemap + + ANIiDnbrCY8YCOtOm1xDrUyt8do= + + PrivateHeaders/NSObject+Swizzling.h + + wRUUMHgrTVWHd/e8bDqN8sYZth4= + + PrivateHeaders/UIView+PropertyBag.h + + 3USXIiZgky+5k7en+R6oyZ3pP18= + + + files2 + + Headers/NSData+Async.h + + hash2 + + JdjuVUBed00Ged4cSDzYLXONUlESu+dae9KN0PYJ/nM= + + + Headers/NSString+Async.h + + hash2 + + 1Iuk4atAJ89zujXqrLBvGz7Ny52RXNdD5c1ZMK0SFgs= + + + Headers/TNSLabel.h + + hash2 + + uaE78Ar4SA7jzBIQrT3lTvBQFOQj1sf1ippa8ldUDqQ= + + + Headers/TNSProcess.h + + hash2 + + E+JvepkSwLMNO6gdhEdwuzkdVTUqmWp8P5LxHYCFim8= + + + Headers/TNSWidgets.h + + hash2 + + V99t2zLwRPOs90tbGiQbhbdAFJlW7mp7X2R5337ewUA= + + + Headers/UIImage+TNSBlocks.h + + hash2 + + MgrX2woetySmXcrrDF290WGxNiW5W3E0B0fsjy8BgNI= + + + Headers/UIView+PassThroughParent.h + + hash2 + + UfHyaUaTFlNcY5M7lUKwq6bPGuQeVIbjhCCInN1ZEYA= + + + Modules/module.modulemap + + hash2 + + geXwbECY3V3psdekq89Ia+2j4/OludM5UatqEk+xhhc= + + + PrivateHeaders/NSObject+Swizzling.h + + hash2 + + S+GqZzjPH/SqyxwzyysFybjZsbwS5lxcTwL04W79IGA= + + + PrivateHeaders/UIView+PropertyBag.h + + hash2 + + /qFTteGRAX+GloVCipAdNRXPDPDWsNmQ+9USxt99lXE= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist new file mode 100644 index 000000000..ef076e371 --- /dev/null +++ b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.org.nativescript.TNSWidgets + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets new file mode 100644 index 000000000..3124a3365 Binary files /dev/null and b/packages/core/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets differ diff --git a/packages/core/ui/animation/animation-interfaces.ts b/packages/core/ui/animation/animation-interfaces.ts index e4e7a7bc9..b953a6bb2 100644 --- a/packages/core/ui/animation/animation-interfaces.ts +++ b/packages/core/ui/animation/animation-interfaces.ts @@ -19,9 +19,9 @@ export type TransformFunctionsInfo = { }; export interface AnimationPromise extends Promise, Cancelable { - then(...args):AnimationPromise - catch(...args):AnimationPromise -}; + then(...args): AnimationPromise; + catch(...args): AnimationPromise; +} export interface Pair { x: number; diff --git a/packages/core/ui/animation/index.android.ts b/packages/core/ui/animation/index.android.ts index 73a5ec2cf..b2aad158d 100644 --- a/packages/core/ui/animation/index.android.ts +++ b/packages/core/ui/animation/index.android.ts @@ -340,7 +340,7 @@ export class Animation extends AnimationBase { animators.push(createObjectAnimator(nativeView, 'alpha', propertyAnimation.value)); break; - case Properties.backgroundColor:{ + case Properties.backgroundColor: { backgroundColorProperty._initDefaultNativeValue(style); ensureArgbEvaluator(); diff --git a/packages/core/ui/animation/index.ios.ts b/packages/core/ui/animation/index.ios.ts index 3873bd990..95714bf44 100644 --- a/packages/core/ui/animation/index.ios.ts +++ b/packages/core/ui/animation/index.ios.ts @@ -380,7 +380,7 @@ export class Animation extends AnimationBase { toValue = NSValue.valueWithCATransform3D(Animation._createNativeAffineTransform(animation)); break; case Properties.width: - case Properties.height:{ + case Properties.height: { const direction: string = animation.property; const isHeight: boolean = direction === 'height'; propertyNameToAnimate = 'bounds'; diff --git a/packages/core/ui/core/view-base/index.ts b/packages/core/ui/core/view-base/index.ts index 76c1748d5..8f7678f67 100644 --- a/packages/core/ui/core/view-base/index.ts +++ b/packages/core/ui/core/view-base/index.ts @@ -47,7 +47,7 @@ export interface ShowModalOptions { /** * A function that will be called when the view is closed. Any arguments provided when calling ShownModallyData.closeCallback will be available here. */ - closeCallback: (...args)=>void; + closeCallback: (...args) => void; /** * An optional parameter specifying whether to show the modal view in full-screen mode. @@ -100,7 +100,7 @@ export interface ShowModalOptions { cancelable?: boolean; } -export function getAncestor(view: ViewBaseDefinition, criterion: string | { new() }): ViewBaseDefinition { +export function getAncestor(view: ViewBaseDefinition, criterion: string | { new () }): ViewBaseDefinition { let matcher: (view: ViewBaseDefinition) => boolean = null; if (typeof criterion === 'string') { matcher = (view: ViewBaseDefinition) => view.typeName === criterion; diff --git a/packages/core/ui/core/view/index.d.ts b/packages/core/ui/core/view/index.d.ts index 4eeec3f88..4ddd4c1ca 100644 --- a/packages/core/ui/core/view/index.d.ts +++ b/packages/core/ui/core/view/index.d.ts @@ -393,6 +393,11 @@ export abstract class View extends ViewBase { */ iosOverflowSafeAreaEnabled: boolean; + /** + * Gets or sets a value indicating whether the the view should totally ignore safe areas computation. This property is iOS specific. Default value: false + */ + iosIgnoreSafeArea: boolean; + /** * Gets is layout is valid. This is a read-only property. */ diff --git a/packages/core/ui/core/view/index.ios.ts b/packages/core/ui/core/view/index.ios.ts index 6558e960a..9543502c7 100644 --- a/packages/core/ui/core/view/index.ios.ts +++ b/packages/core/ui/core/view/index.ios.ts @@ -275,8 +275,8 @@ export class View extends ViewCommon implements ViewDefinition { return null; } if (this.iosIgnoreSafeArea) { - return frame; - } + return frame; + } if (!this.iosOverflowSafeArea || !this.iosOverflowSafeAreaEnabled) { return IOSHelper.shrinkToSafeArea(this, frame); } else if (this.nativeViewProtected && this.nativeViewProtected.window) { @@ -290,8 +290,8 @@ export class View extends ViewCommon implements ViewDefinition { const safeAreaInsets = this.nativeViewProtected && this.nativeViewProtected.safeAreaInsets; const insets = { left: 0, top: 0, right: 0, bottom: 0 }; if (this.iosIgnoreSafeArea) { - return insets; - } + return insets; + } if (safeAreaInsets) { insets.left = layout.round(layout.toDevicePixels(safeAreaInsets.left)); insets.top = layout.round(layout.toDevicePixels(safeAreaInsets.top)); diff --git a/packages/core/ui/core/view/view-common.ts b/packages/core/ui/core/view/view-common.ts index d9beeb832..552b92c0b 100644 --- a/packages/core/ui/core/view/view-common.ts +++ b/packages/core/ui/core/view/view-common.ts @@ -765,7 +765,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition { public iosOverflowSafeArea: boolean; public iosOverflowSafeAreaEnabled: boolean; public iosIgnoreSafeArea: boolean; - + get isLayoutValid(): boolean { return this._isLayoutValid; } @@ -1063,8 +1063,8 @@ export const iosOverflowSafeAreaEnabledProperty = new InheritedProperty this._goToVisualState('focus'); private _blurHandler = () => this._goToVisualState('blur'); diff --git a/packages/core/ui/editable-text-base/index.android.ts b/packages/core/ui/editable-text-base/index.android.ts index 12e14d9cf..e9a41db03 100644 --- a/packages/core/ui/editable-text-base/index.android.ts +++ b/packages/core/ui/editable-text-base/index.android.ts @@ -144,6 +144,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { /* tslint:enable */ nativeViewProtected: android.widget.EditText; + nativeTextViewProtected: android.widget.EditText; private _keyListenerCache: android.text.method.KeyListener; private _inputType: number; @@ -327,7 +328,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { case 'send': newImeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEND; break; - default:{ + default: { const ime = +value; if (!isNaN(ime)) { newImeOptions = ime; @@ -382,7 +383,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { case 'allcharacters': inputType = inputType | android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS; //4096 (0x00010000) 13th bit break; - default:{ + default: { const number = +value; // We set the default value. if (!isNaN(number)) { @@ -466,4 +467,15 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { this.nativeTextViewProtected.setFilters(newFilters); } } + + public setSelection(start: number, stop?: number) { + const view = this.nativeTextViewProtected; + if (view) { + if (stop !== undefined) { + view.setSelection(start, stop); + } else { + view.setSelection(start); + } + } + } } diff --git a/packages/core/ui/editable-text-base/index.d.ts b/packages/core/ui/editable-text-base/index.d.ts index 87614e380..b144ab044 100644 --- a/packages/core/ui/editable-text-base/index.d.ts +++ b/packages/core/ui/editable-text-base/index.d.ts @@ -64,6 +64,11 @@ export class EditableTextBase extends TextBase { */ public _setInputType(inputType: number): void; //@endprivate + + /** + * Set the selection anchor to start and the selection edge to stop + */ + public setSelection(start: number, stop?: number); } export type ReturnKeyType = 'done' | 'next' | 'go' | 'search' | 'send'; diff --git a/packages/core/ui/editable-text-base/index.ios.ts b/packages/core/ui/editable-text-base/index.ios.ts index 900df7e7b..6af98a69b 100644 --- a/packages/core/ui/editable-text-base/index.ios.ts +++ b/packages/core/ui/editable-text-base/index.ios.ts @@ -5,6 +5,7 @@ export * from './editable-text-base-common'; export abstract class EditableTextBase extends EditableTextBaseCommon { public nativeViewProtected: UITextField | UITextView; + public readonly nativeTextViewProtected: UITextField | UITextView; public dismissSoftInput() { this.nativeTextViewProtected.resignFirstResponder(); this.notify({ eventName: EditableTextBase.blurEvent, object: this }); @@ -189,6 +190,21 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { this.nativeTextViewProtected.autocorrectionType = newValue; } + public setSelection(start: number, stop?: number) { + const view = this.nativeTextViewProtected; + if (view) { + if (stop !== undefined) { + const begin = view.beginningOfDocument; + const fromPosition = view.positionFromPositionOffset(begin, start); + const toPosition = view.positionFromPositionOffset(begin, stop); + view.selectedTextRange = view.textRangeFromPositionToPosition(fromPosition, toPosition); + } else { + const begin = view.beginningOfDocument; + const pos = view.positionFromPositionOffset(begin, start); + view.selectedTextRange = view.textRangeFromPositionToPosition(pos, pos); + } + } + } } export function _updateCharactersInRangeReplacementString(formattedText: FormattedString, rangeLocation: number, rangeLength: number, replacementString: string): void { diff --git a/packages/core/ui/frame/frame-common.ts b/packages/core/ui/frame/frame-common.ts index a116fe729..b7c58e446 100644 --- a/packages/core/ui/frame/frame-common.ts +++ b/packages/core/ui/frame/frame-common.ts @@ -10,6 +10,7 @@ import { getAncestor } from '../core/view-base'; import { Builder } from '../builder'; import { sanitizeModuleName } from '../builder/module-name-sanitizer'; import { profile } from '../../profiling'; +import { FRAME_SYMBOL } from './frame-helpers'; export { NavigationType } from './frame-interfaces'; export type { AndroidActivityCallbacks, AndroidFragmentCallbacks, AndroidFrame, BackstackEntry, NavigationContext, NavigationEntry, NavigationTransition, TransitionState, ViewEntry, iOSFrame } from './frame-interfaces'; @@ -424,7 +425,7 @@ export class FrameBase extends CustomLayoutView { object: this, isBack, entry: backstackEntry.entry, - fromEntry:this.currentEntry + fromEntry: this.currentEntry, }); } @@ -696,6 +697,9 @@ export class FrameBase extends CustomLayoutView { } } +// Mark as a Frame with an unique Symbol +FrameBase.prototype[FRAME_SYMBOL] = true; + export function getFrameById(id: string): FrameBase { console.log('getFrameById() is deprecated. Use Frame.getFrameById() instead.'); diff --git a/packages/core/ui/frame/frame-helpers.ts b/packages/core/ui/frame/frame-helpers.ts new file mode 100644 index 000000000..73d996d58 --- /dev/null +++ b/packages/core/ui/frame/frame-helpers.ts @@ -0,0 +1,19 @@ +/** + * Unique symbol to mark Frame instances. + * + * We use a symbol because in some cases importing the Frame to do + * instanceof checks introduces circular references. + * + * Having the symbol in it's own file prevents any potential circular + * references and allows checking if an object is a frame + */ +export const FRAME_SYMBOL = Symbol('FRAME_SYMBOL'); + +/** + * Helper to determine if the passed object is a Frame + * + * @param object + */ +export function isFrame(object: any) { + return object && object[FRAME_SYMBOL] === true; +} diff --git a/packages/core/ui/frame/index.d.ts b/packages/core/ui/frame/index.d.ts index dabdcda93..7296d76f1 100644 --- a/packages/core/ui/frame/index.d.ts +++ b/packages/core/ui/frame/index.d.ts @@ -6,7 +6,7 @@ import { Transition } from '../transition'; export * from './frame-interfaces'; -export interface NavigationData extends EventData { +export interface NavigationData extends EventData { entry?: NavigationEntry; fromEntry?: NavigationEntry; isBack?: boolean; diff --git a/packages/core/ui/frame/index.ios.ts b/packages/core/ui/frame/index.ios.ts index f2bed6dd8..9ac12b496 100644 --- a/packages/core/ui/frame/index.ios.ts +++ b/packages/core/ui/frame/index.ios.ts @@ -54,7 +54,7 @@ export class Frame extends FrameBase { public setCurrent(entry: BackstackEntry, navigationType: NavigationType): void { const current = this._currentEntry; const currentEntryChanged = current !== entry; - if (currentEntryChanged) { + if (entry?.resolvedPage && currentEntryChanged) { this._updateBackstack(entry, navigationType); super.setCurrent(entry, navigationType); @@ -249,7 +249,7 @@ export class Frame extends FrameBase { case 'never': return false; - case 'auto':{ + case 'auto': { let newValue: boolean; if (page && page.actionBarHidden !== undefined) { diff --git a/packages/core/ui/gestures/index.android.ts b/packages/core/ui/gestures/index.android.ts index a58a55d51..071f16d5b 100644 --- a/packages/core/ui/gestures/index.android.ts +++ b/packages/core/ui/gestures/index.android.ts @@ -565,7 +565,7 @@ class CustomRotateGestureDetector { switch (event.getActionMasked()) { case android.view.MotionEvent.ACTION_DOWN: - case android.view.MotionEvent.ACTION_POINTER_DOWN:{ + case android.view.MotionEvent.ACTION_POINTER_DOWN: { let assigned = false; if (this.trackedPtrId1 === INVALID_POINTER_ID && pointerID !== this.trackedPtrId2) { this.trackedPtrId1 = pointerID; diff --git a/packages/core/ui/layouts/flexbox-layout/flexbox-layout-common.ts b/packages/core/ui/layouts/flexbox-layout/flexbox-layout-common.ts index 5bd7c42d6..98918586e 100644 --- a/packages/core/ui/layouts/flexbox-layout/flexbox-layout-common.ts +++ b/packages/core/ui/layouts/flexbox-layout/flexbox-layout-common.ts @@ -36,7 +36,7 @@ export namespace JustifyContent { export const FLEX_END = 'flex-end' as const; export const CENTER = 'center' as const; export const SPACE_BETWEEN = 'space-between'; - export const SPACE_AROUND= 'space-around'; + export const SPACE_AROUND = 'space-around'; export const isValid = makeValidator(FLEX_START, FLEX_END, CENTER, SPACE_BETWEEN, SPACE_AROUND); export const parse = makeParser(isValid); @@ -50,7 +50,7 @@ export namespace FlexBasisPercent { export type AlignItems = 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch'; export namespace AlignItems { export const FLEX_START = 'flex-start'; - export const FLEX_END= 'flex-end'; + export const FLEX_END = 'flex-end'; export const CENTER = 'center'; export const BASELINE = 'baseline'; export const STRETCH = 'stretch'; diff --git a/packages/core/ui/layouts/flexbox-layout/index.ios.ts b/packages/core/ui/layouts/flexbox-layout/index.ios.ts index 8ae9b80c1..9ac6fafc8 100644 --- a/packages/core/ui/layouts/flexbox-layout/index.ios.ts +++ b/packages/core/ui/layouts/flexbox-layout/index.ios.ts @@ -463,7 +463,7 @@ export class FlexboxLayout extends FlexboxLayoutBase { switch (flexDirection) { case FlexDirection.ROW: - case FlexDirection.ROW_REVERSE:{ + case FlexDirection.ROW_REVERSE: { const widthMode = getMeasureSpecMode(widthMeasureSpec); const widthSize = getMeasureSpecSize(widthMeasureSpec); if (widthMode === EXACTLY) { @@ -475,7 +475,7 @@ export class FlexboxLayout extends FlexboxLayoutBase { break; } case FlexDirection.COLUMN: - case FlexDirection.COLUMN_REVERSE:{ + case FlexDirection.COLUMN_REVERSE: { const heightMode = getMeasureSpecMode(heightMeasureSpec); const heightSize = getMeasureSpecSize(heightMeasureSpec); if (heightMode === EXACTLY) { @@ -1019,7 +1019,7 @@ export class FlexboxLayout extends FlexboxLayoutBase { childLeft = paddingLeft + spaceBetweenItem / 2.0; childRight = width - paddingRight - spaceBetweenItem / 2.0; break; - case JustifyContent.SPACE_BETWEEN:{ + case JustifyContent.SPACE_BETWEEN: { childLeft = paddingLeft; const denominator = flexLine.itemCount !== 1 ? flexLine.itemCount - 1 : 1.0; spaceBetweenItem = (width - insets.left - insets.right - flexLine.mainSize) / denominator; @@ -1110,7 +1110,7 @@ export class FlexboxLayout extends FlexboxLayoutBase { view.layout(left, top - crossSize + view.getMeasuredHeight() + lp.effectiveMarginTop, right, bottom - crossSize + view.getMeasuredHeight() + lp.effectiveMarginTop); } break; - case AlignItems.CENTER:{ + case AlignItems.CENTER: { const topFromCrossAxis = (crossSize - view.getMeasuredHeight()) / 2; if (flexWrap !== FlexWrap.WRAP_REVERSE) { view.layout(left, top + topFromCrossAxis + lp.effectiveMarginTop - lp.effectiveMarginBottom, right, top + topFromCrossAxis + view.getMeasuredHeight() + lp.effectiveMarginTop - lp.effectiveMarginBottom); @@ -1163,7 +1163,7 @@ export class FlexboxLayout extends FlexboxLayoutBase { childTop = paddingTop + spaceBetweenItem / 2.0; childBottom = height - paddingBottom - spaceBetweenItem / 2.0; break; - case JustifyContent.SPACE_BETWEEN:{ + case JustifyContent.SPACE_BETWEEN: { childTop = paddingTop; const denominator = flexLine.itemCount !== 1 ? flexLine.itemCount - 1 : 1.0; spaceBetweenItem = (height - insets.top - insets.bottom - flexLine.mainSize) / denominator; @@ -1244,7 +1244,7 @@ export class FlexboxLayout extends FlexboxLayoutBase { view.layout(left - crossSize + view.getMeasuredWidth() + lp.effectiveMarginLeft, top, right - crossSize + view.getMeasuredWidth() + lp.effectiveMarginLeft, bottom); } break; - case AlignItems.CENTER:{ + case AlignItems.CENTER: { const leftFromCrossAxis = (crossSize - view.getMeasuredWidth()) / 2; if (!isRtl) { view.layout(left + leftFromCrossAxis + lp.effectiveMarginLeft - lp.effectiveMarginRight, top, right + leftFromCrossAxis + lp.effectiveMarginLeft - lp.effectiveMarginRight, bottom); diff --git a/packages/core/ui/page/index.ios.ts b/packages/core/ui/page/index.ios.ts index a0df7c5d1..afd99aca9 100644 --- a/packages/core/ui/page/index.ios.ts +++ b/packages/core/ui/page/index.ios.ts @@ -214,7 +214,7 @@ class UIViewControllerImpl extends UIViewController { // or because we are closing a modal page, // or because we are in tab and another controller is selected. const tab = this.tabBarController; - if (owner.onNavigatingFrom && !owner._presentedViewController && !this.presentingViewController && frame && frame.currentPage === owner) { + if (owner.onNavigatingFrom && !owner._presentedViewController && frame && (!this.presentingViewController || frame.backStack.length > 0) && frame.currentPage === owner) { const willSelectViewController = tab && (tab)._willSelectViewController; if (!willSelectViewController || willSelectViewController === tab.selectedViewController) { const isBack = isBackNavigationFrom(this, owner); diff --git a/packages/core/ui/page/page-common.ts b/packages/core/ui/page/page-common.ts index f6280f19e..a9526656a 100644 --- a/packages/core/ui/page/page-common.ts +++ b/packages/core/ui/page/page-common.ts @@ -7,6 +7,7 @@ import { Style } from '../styling/style'; import { Color } from '../../color'; import { EventData } from '../../data/observable'; import type { Frame } from '../frame'; +import { isFrame } from '../frame/frame-helpers'; import { ActionBar } from '../action-bar'; import { KeyframeAnimationInfo } from '../animation/keyframe-animation'; import { profile } from '../../profiling'; @@ -92,9 +93,9 @@ export class PageBase extends ContentView { } get frame(): Frame { - const frame = this.parent; + const parent = this.parent; - return (frame && frame.constructor.name === 'Frame') ? frame as Frame : undefined; + return isFrame(parent) ? (parent as Frame) : undefined; } private createNavigatedData(eventName: string, isBackNavigation: boolean): NavigatedData { diff --git a/packages/core/ui/styling/background.android.ts b/packages/core/ui/styling/background.android.ts index 90204423e..65459fdb9 100644 --- a/packages/core/ui/styling/background.android.ts +++ b/packages/core/ui/styling/background.android.ts @@ -44,12 +44,13 @@ export namespace ad { const constantState = drawable.getConstantState(); androidView._cachedDrawable = constantState || drawable; } + const isBorderDrawable = drawable instanceof org.nativescript.widgets.BorderDrawable; const onlyColor = !background.hasBorderWidth() && !background.hasBorderRadius() && !background.clipPath && !background.image && !!background.color; - if (drawable instanceof android.graphics.drawable.ColorDrawable && onlyColor) { + if (!isBorderDrawable && drawable instanceof android.graphics.drawable.ColorDrawable && onlyColor) { drawable.setColor(background.color.android); drawable.invalidateSelf(); } else if (isSetColorFilterOnlyWidget(nativeView) && drawable && onlyColor) { - if (drawable instanceof org.nativescript.widgets.BorderDrawable && androidView._cachedDrawable) { + if (isBorderDrawable && androidView._cachedDrawable) { if (!(androidView._cachedDrawable instanceof android.graphics.drawable.Drawable.ConstantState)) { return; } @@ -63,12 +64,12 @@ export namespace ad { drawable.setColorFilter(backgroundColor, android.graphics.PorterDuff.Mode.SRC_IN); drawable.invalidateSelf(); // Make sure the drawable is invalidated. Android forgets to invalidate it in some cases: toolbar (drawable).backgroundColor = backgroundColor; - } else if (onlyColor) { + } else if (!isBorderDrawable && onlyColor) { // this is the fastest way to change only background color nativeView.setBackgroundColor(background.color.android); } else if (!background.isEmpty()) { let backgroundDrawable = drawable as org.nativescript.widgets.BorderDrawable; - if (!(drawable instanceof org.nativescript.widgets.BorderDrawable)) { + if (!isBorderDrawable) { backgroundDrawable = new org.nativescript.widgets.BorderDrawable(layout.getDisplayDensity(), view.toString()); refreshBorderDrawable(view, backgroundDrawable); nativeView.setBackground(backgroundDrawable); diff --git a/packages/core/ui/styling/style-scope.ts b/packages/core/ui/styling/style-scope.ts index 46128aa9f..38bcbef29 100644 --- a/packages/core/ui/styling/style-scope.ts +++ b/packages/core/ui/styling/style-scope.ts @@ -216,7 +216,7 @@ class CSSSource { const cssTreeParse = require('../../css/css-tree-parser').cssTreeParse; this._ast = cssTreeParse(this._source, this._file); return; - case 'nativescript':{ + case 'nativescript': { const CSS3Parser = require('../../css/parser').CSS3Parser; const CSSNativeScript = require('../../css/parser').CSSNativeScript; const cssparser = new CSS3Parser(this._source); @@ -475,7 +475,10 @@ export class CssState { const matchingSelectors = this._match.selectors.filter((sel) => (sel.dynamic ? sel.match(view) : true)); if (!matchingSelectors || matchingSelectors.length === 0) { - return; + // Ideally we should return here if there are no matching selectors, however + // if there are property removals, returning here would not remove them + // this is seen in STYLE test in automated. + // return; } view._batchUpdate(() => { this.stopKeyframeAnimations(); @@ -578,23 +581,23 @@ export class CssState { } if (isCssVariableExpression(value) || isCssCalcExpression(value)) { value = evaluateCssExpressions(view, property, newPropertyValues[property]); - } - if (value === unsetValue) { - delete newPropertyValues[property]; - continue; - } + } + if (value === unsetValue) { + delete newPropertyValues[property]; + continue; + } valuesToApply[property] = value; } // Unset removed values for (const property in oldProperties) { - if (property in view.style) { - view.style[`css:${property}`] = unsetValue; + if (property in view.style) { + view.style[`css:${property}`] = unsetValue; } else { - // TRICKY: How do we unset local value? + // TRICKY: How do we unset local value? + } } - } // Set new values to the style for (const property in valuesToApply) { const value = valuesToApply[property]; diff --git a/packages/core/ui/text-field/index.ios.ts b/packages/core/ui/text-field/index.ios.ts index c43f972f1..877f35f0d 100644 --- a/packages/core/ui/text-field/index.ios.ts +++ b/packages/core/ui/text-field/index.ios.ts @@ -217,7 +217,10 @@ export class TextField extends TextFieldBase { if (this.formattedText) { _updateCharactersInRangeReplacementString(this.formattedText, range.location, range.length, replacementString); } - + if (this.width === 'auto') { + // if the textfield is in auto size we need to request a layout to take the new text width into account + this.requestLayout(); + } this.firstEdit = false; return true; diff --git a/packages/core/utils/native-helper.d.ts b/packages/core/utils/native-helper.d.ts index 5ad5fc2e5..69212d6ce 100644 --- a/packages/core/utils/native-helper.d.ts +++ b/packages/core/utils/native-helper.d.ts @@ -168,9 +168,9 @@ export namespace iOSNativeHelper { */ export function applyRotateTransform(transform: any /* CATransform3D*/, x: number, y: number, z: number): any; /* CATransform3D*/ - /** - * Create a UIDocumentInteractionControllerDelegate implementation for use with UIDocumentInteractionController - */ + /** + * Create a UIDocumentInteractionControllerDelegate implementation for use with UIDocumentInteractionController + */ export function createUIDocumentInteractionControllerDelegate(): any; /** diff --git a/packages/core/utils/native-helper.ios.ts b/packages/core/utils/native-helper.ios.ts index ebddd3f0f..a9db0611a 100644 --- a/packages/core/utils/native-helper.ios.ts +++ b/packages/core/utils/native-helper.ios.ts @@ -96,19 +96,12 @@ export namespace iOSNativeHelper { } export function getVisibleViewController(rootViewController: UIViewController): UIViewController { - if (rootViewController.presentedViewController) { - return getVisibleViewController(rootViewController.presentedViewController); - } + let viewController = rootViewController; - if (rootViewController.isKindOfClass(UINavigationController.class())) { - return getVisibleViewController((rootViewController).visibleViewController); + while (viewController && viewController.presentedViewController) { + viewController = viewController.presentedViewController; } - - if (rootViewController.isKindOfClass(UITabBarController.class())) { - return getVisibleViewController(rootViewController); - } - - return rootViewController; + return viewController; } export function applyRotateTransform(transform: CATransform3D, x: number, y: number, z: number): CATransform3D { @@ -125,33 +118,33 @@ export namespace iOSNativeHelper { } return transform; - } - - export function createUIDocumentInteractionControllerDelegate(): NSObject { - @NativeClass - class UIDocumentInteractionControllerDelegateImpl extends NSObject implements UIDocumentInteractionControllerDelegate { - public static ObjCProtocols = [UIDocumentInteractionControllerDelegate]; - - public getViewController(): UIViewController { - const app = UIApplication.sharedApplication; - - return app.keyWindow.rootViewController; - } - - public documentInteractionControllerViewControllerForPreview(controller: UIDocumentInteractionController) { - return this.getViewController(); - } - - public documentInteractionControllerViewForPreview(controller: UIDocumentInteractionController) { - return this.getViewController().view; - } - - public documentInteractionControllerRectForPreview(controller: UIDocumentInteractionController): CGRect { - return this.getViewController().view.frame; - } - } - return new UIDocumentInteractionControllerDelegateImpl(); - } + } + + export function createUIDocumentInteractionControllerDelegate(): NSObject { + @NativeClass + class UIDocumentInteractionControllerDelegateImpl extends NSObject implements UIDocumentInteractionControllerDelegate { + public static ObjCProtocols = [UIDocumentInteractionControllerDelegate]; + + public getViewController(): UIViewController { + const app = UIApplication.sharedApplication; + + return app.keyWindow.rootViewController; + } + + public documentInteractionControllerViewControllerForPreview(controller: UIDocumentInteractionController) { + return this.getViewController(); + } + + public documentInteractionControllerViewForPreview(controller: UIDocumentInteractionController) { + return this.getViewController().view; + } + + public documentInteractionControllerRectForPreview(controller: UIDocumentInteractionController): CGRect { + return this.getViewController().view.frame; + } + } + return new UIDocumentInteractionControllerDelegateImpl(); + } export function isRealDevice() { try { diff --git a/packages/types-android/package.json b/packages/types-android/package.json index eb8e90e46..cc672b6e8 100644 --- a/packages/types-android/package.json +++ b/packages/types-android/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/types-android", - "version": "7.1.0", + "version": "7.2.0", "description": "NativeScript Types for Android.", "homepage": "https://nativescript.org", "repository": { diff --git a/packages/types-ios/package.json b/packages/types-ios/package.json index 1963ab6ac..44d082950 100644 --- a/packages/types-ios/package.json +++ b/packages/types-ios/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/types-ios", - "version": "7.1.0", + "version": "7.2.0", "description": "NativeScript Types for iOS.", "homepage": "https://nativescript.org", "repository": { diff --git a/packages/types-ios/src/lib/ios/objc-x86_64/objc!ExposureNotification.d.ts b/packages/types-ios/src/lib/ios/objc-x86_64/objc!ExposureNotification.d.ts index 3053bbdc3..c5d224582 100644 --- a/packages/types-ios/src/lib/ios/objc-x86_64/objc!ExposureNotification.d.ts +++ b/packages/types-ios/src/lib/ios/objc-x86_64/objc!ExposureNotification.d.ts @@ -1,4 +1,15 @@ +declare const enum ENActivityFlags { + + Reserved1 = 1, + + Reserved2 = 2, + + PeriodicRun = 4, + + PreAuthorizedKeyReleaseNotificationTapped = 8 +} + declare const ENAttenuationMax: number; declare const ENAttenuationMin: number; @@ -252,6 +263,10 @@ declare class ENManager extends NSObject { static new(): ENManager; // inherited from NSObject + activityHandler: (p1: ENActivityFlags) => void; + + diagnosisKeysAvailableHandler: (p1: NSArray) => void; + dispatchQueue: NSObject; readonly exposureNotificationEnabled: boolean; @@ -280,6 +295,10 @@ declare class ENManager extends NSObject { invalidate(): void; + preAuthorizeDiagnosisKeysWithCompletionHandler(completionHandler: (p1: NSError) => void): void; + + requestPreAuthorizedDiagnosisKeysWithCompletionHandler(completionHandler: (p1: NSError) => void): void; + setExposureNotificationEnabledCompletionHandler(enabled: boolean, completionHandler: (p1: NSError) => void): void; } diff --git a/packages/types/package.json b/packages/types/package.json index 688431db1..388909b35 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/types", - "version": "7.1.0", + "version": "7.2.0", "description": "NativeScript Types for all supported platforms.", "homepage": "https://nativescript.org", "repository": { @@ -12,7 +12,7 @@ ], "license": "Apache-2.0", "dependencies": { - "@nativescript/types-ios": "7.1.0", - "@nativescript/types-android": "7.1.0" + "@nativescript/types-ios": "7.2.0", + "@nativescript/types-android": "7.2.0" } } diff --git a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/FlexboxLayout.java b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/FlexboxLayout.java index ca02e3007..3798a3479 100644 --- a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/FlexboxLayout.java +++ b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/FlexboxLayout.java @@ -74,7 +74,7 @@ import java.util.List; *
  • {@code layout_wrapBefore}
  • * */ -public class FlexboxLayout extends ViewGroup { +public class FlexboxLayout extends LayoutBase { @IntDef({FLEX_DIRECTION_ROW, FLEX_DIRECTION_ROW_REVERSE, FLEX_DIRECTION_COLUMN, FLEX_DIRECTION_COLUMN_REVERSE}) @@ -2226,6 +2226,11 @@ public class FlexboxLayout extends ViewGroup { mDividerDrawableHorizontal.draw(canvas); } + @Override + protected LayoutParams generateDefaultLayoutParams() { + return new FlexboxLayout.LayoutParams(); + } + @Override protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { return p instanceof FlexboxLayout.LayoutParams; diff --git a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/LayoutBase.java b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/LayoutBase.java index ee9e3227c..7a3abe8ac 100644 --- a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/LayoutBase.java +++ b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/LayoutBase.java @@ -16,16 +16,16 @@ import android.widget.FrameLayout; * */ public abstract class LayoutBase extends ViewGroup { + private boolean passThroughParent; + + public LayoutBase(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } public LayoutBase(Context context) { super(context); } - - private boolean passThroughParent; - - public boolean getPassThroughParent() { return this.passThroughParent; } - public void setPassThroughParent(boolean value) { this.passThroughParent = value; } - + @Override protected LayoutParams generateDefaultLayoutParams() { return new CommonLayoutParams(); @@ -91,4 +91,12 @@ public abstract class LayoutBase extends ViewGroup { return gravity; } + + public boolean getPassThroughParent() { + return this.passThroughParent; + } + + public void setPassThroughParent(boolean value) { + this.passThroughParent = value; + } } \ No newline at end of file diff --git a/packages/ui-mobile-base/build.ios.sh b/packages/ui-mobile-base/build.ios.sh index 79736026c..3c3e2e795 100755 --- a/packages/ui-mobile-base/build.ios.sh +++ b/packages/ui-mobile-base/build.ios.sh @@ -14,11 +14,11 @@ echo "Build iOS" cd ios ./build.sh cd .. -echo "Copy ios/TNSWidgets/build/*.framework dist/package/platforms/ios" +echo "Copy ios/TNSWidgets/build/*.xcframework dist/package/platforms/ios" -cp -R ios/TNSWidgets/build/TNSWidgets.framework dist/package/platforms/ios +cp -R ios/TNSWidgets/build/TNSWidgets.xcframework dist/package/platforms/ios -cp ios/TNSWidgets/build/*.framework.dSYM.zip dist/package/platforms/ios +# cp ios/TNSWidgets/build/*.framework.dSYM.zip dist/package/platforms/ios if [ "$1" ] then @@ -30,7 +30,7 @@ if [ "$SKIP_PACK" ] then echo "SKIP pack" else - echo "Copy NPM artefacts" + echo "Copy NPM artifacts" cp .npmignore LICENSE README.md package.json dist/package echo "NPM pack" cd dist/package diff --git a/packages/ui-mobile-base/build.sh b/packages/ui-mobile-base/build.sh index 4d39c9cd5..e7f449d02 100755 --- a/packages/ui-mobile-base/build.sh +++ b/packages/ui-mobile-base/build.sh @@ -14,7 +14,7 @@ export SKIP_PACK=true ./build.android.sh ./build.ios.sh -echo "Copy NPM artefacts" +echo "Copy NPM artifacts" cp .npmignore README.md package.json dist/package cp ../../LICENSE dist/package diff --git a/packages/ui-mobile-base/ios/TNSWidgets/TNSProcess.h b/packages/ui-mobile-base/ios/TNSWidgets/TNSProcess.h index baea95509..d2f657014 100644 --- a/packages/ui-mobile-base/ios/TNSWidgets/TNSProcess.h +++ b/packages/ui-mobile-base/ios/TNSWidgets/TNSProcess.h @@ -14,7 +14,7 @@ /** * Get the milliseconds since the process started. */ -double __tns_uptime(); +double __tns_uptime(void); /** * Provides access to NSLog. The runtime implementation of console.log is filtered in release. diff --git a/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.pbxproj b/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.pbxproj index f57d5413e..50817817c 100644 --- a/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.pbxproj +++ b/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.pbxproj @@ -198,7 +198,7 @@ F98F5CA61CD0EFEA00978308 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0720; + LastUpgradeCheck = 1230; ORGANIZATIONNAME = "Telerik A D"; TargetAttributes = { F98F5CAE1CD0EFEA00978308 = { @@ -284,17 +284,29 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -317,7 +329,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.2; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -331,17 +343,29 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -358,7 +382,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.2; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -372,6 +396,7 @@ isa = XCBuildConfiguration; buildSettings = { BITCODE_GENERATION_MODE = bitcode; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -389,6 +414,7 @@ isa = XCBuildConfiguration; buildSettings = { BITCODE_GENERATION_MODE = bitcode; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; diff --git a/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b67898..3ddf867a1 100644 --- a/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -3,6 +3,6 @@ BuildSystemType - Original + Latest diff --git a/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets/NSData+Async.h b/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets/NSData+Async.h index 36508cc54..3e0cc8207 100644 --- a/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets/NSData+Async.h +++ b/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets/NSData+Async.h @@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)writeToFile:(nonnull NSString*) path atomically:(BOOL)atomically - completion:(void (^) ())callback; + completion:(void (^) (void))callback; @end diff --git a/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets/NSData+Async.m b/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets/NSData+Async.m index 2f6b0a37b..a512eda43 100644 --- a/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets/NSData+Async.m +++ b/packages/ui-mobile-base/ios/TNSWidgets/TNSWidgets/NSData+Async.m @@ -25,7 +25,7 @@ - (void)writeToFile:(nonnull NSString*) path atomically:(BOOL)atomically - completion:(void (^) ())callback { + completion:(void (^) (void))callback { dispatch_queue_t asyncQueue = dispatch_queue_create("org.nativescript.TNSWidgets.data", NULL); dispatch_async(asyncQueue, ^(void) { diff --git a/packages/ui-mobile-base/ios/build.sh b/packages/ui-mobile-base/ios/build.sh index 674f8647f..ccac07458 100755 --- a/packages/ui-mobile-base/ios/build.sh +++ b/packages/ui-mobile-base/ios/build.sh @@ -3,45 +3,37 @@ echo "Set exit on simple errors" set -e -echo "Build for iphonesimulator" -xcodebuild -project TNSWidgets/TNSWidgets.xcodeproj -scheme TNSWidgets -sdk iphonesimulator -configuration Release clean build BUILD_DIR=$(PWD)/TNSWidgets/build -quiet -xcconfig "TNSWidgets/build.xcconfig" +rm -rf $(PWD)/TNSWidgets/build +echo "Build for iphonesimulator" +xcodebuild \ + -project TNSWidgets/TNSWidgets.xcodeproj \ + -scheme TNSWidgets \ + -sdk iphonesimulator \ + -configuration Release \ + clean build \ + BUILD_DIR=$(PWD)/TNSWidgets/build \ + SKIP_INSTALL=NO \ + -quiet echo "Build for iphoneos" -xcodebuild -project TNSWidgets/TNSWidgets.xcodeproj -scheme TNSWidgets -sdk iphoneos -configuration Release clean build BUILD_DIR=$(PWD)/TNSWidgets/build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -quiet -xcconfig "TNSWidgets/build.xcconfig" +xcodebuild \ + -project TNSWidgets/TNSWidgets.xcodeproj \ + -scheme TNSWidgets \ + -sdk iphoneos \ + -configuration Release \ + clean build \ + BUILD_DIR=$(PWD)/TNSWidgets/build \ + CODE_SIGN_IDENTITY="" \ + CODE_SIGNING_REQUIRED=NO \ + SKIP_INSTALL=NO \ + -quiet -function buildFatFramework() { - FRAMEWORK_NAME=$1 - RELATIVE_DIR=$2 - SRC_IPHONEOS=TNSWidgets/build/Release-iphoneos/$RELATIVE_DIR/$FRAMEWORK_NAME.framework - SRC_SIMULATOR=TNSWidgets/build/Release-iphonesimulator/$RELATIVE_DIR/$FRAMEWORK_NAME.framework - DEST=TNSWidgets/build/$FRAMEWORK_NAME.framework - echo; echo "Build fat framework at $DEST" - rm -rf $DEST - mkdir $DEST - - cp -r `find $SRC_IPHONEOS -depth 1 | grep -v 'PrivateHeaders'` $DEST/ - - lipo -create $SRC_IPHONEOS/$FRAMEWORK_NAME $SRC_SIMULATOR/$FRAMEWORK_NAME -o $DEST/$FRAMEWORK_NAME - file $DEST/$FRAMEWORK_NAME - - if [ -d $SRC_IPHONEOS.dSYM ]; then - echo "Build fat dSYM at $DEST.dSYM" - cp -r $SRC_IPHONEOS.dSYM TNSWidgets/build - rm "$DEST.dSYM/Contents/Resources/DWARF/$FRAMEWORK_NAME" - lipo -create -output "$DEST.dSYM/Contents/Resources/DWARF/$FRAMEWORK_NAME" \ - "$SRC_SIMULATOR.dSYM/Contents/Resources/DWARF/$FRAMEWORK_NAME" \ - "$SRC_IPHONEOS.dSYM/Contents/Resources/DWARF/$FRAMEWORK_NAME" - file $DEST.dSYM/Contents/Resources/DWARF/$FRAMEWORK_NAME - - echo "Archiving dSYM at $DEST.dSYM.zip" - (cd TNSWidgets/build && zip -qr $FRAMEWORK_NAME.framework.dSYM.zip $FRAMEWORK_NAME.framework.dSYM) - - echo "Removing $DEST.dSYM" - rm -rf $DEST.dSYM - else - echo "info: $SRC_IPHONEOS.dSYM doesn't exist. Skipping dSYM archive." - fi -} - -buildFatFramework TNSWidgets . +echo "Creating XCFramework" +xcodebuild \ + -create-xcframework \ + -framework $(PWD)/TNSWidgets/build/Release-iphoneos/TNSWidgets.framework \ + -debug-symbols $(PWD)/TNSWidgets/build/Release-iphoneos/TNSWidgets.framework.dSYM \ + -framework $(PWD)/TNSWidgets/build/Release-iphonesimulator/TNSWidgets.framework \ + -debug-symbols $(PWD)/TNSWidgets/build/Release-iphonesimulator/TNSWidgets.framework.dSYM \ + -output $(PWD)/TNSWidgets/build/TNSWidgets.xcframework diff --git a/packages/webpack/host/resolver.ts b/packages/webpack/host/resolver.ts index 0b4067539..c861a3ec1 100644 --- a/packages/webpack/host/resolver.ts +++ b/packages/webpack/host/resolver.ts @@ -7,18 +7,6 @@ export function getResolver(platforms: string[], explicitResolve?: string[], nsP platformSpecificExt = platformSpecificExt || ['.ts', '.js', '.scss', '.less', '.css', '.html', '.xml', '.vue', '.json']; return function (path: string) { - const nmIndex = path.lastIndexOf('node_modules'); - - if (nmIndex !== -1) { - const subPath = path.substr(nmIndex + 'node_modules'.length).replace(/\\/g, '/'); - const shouldResolve = explicitResolve.length && explicitResolve.some((packageName) => subPath.indexOf(packageName) !== -1); - const pathParts = subPath.split(/[/\-_]/); - - if (!shouldResolve && pathParts.every((p) => nsPackageFilters.every((f) => f !== p))) { - return path; - } - } - const { dir, name, ext } = parse(path); if (platformSpecificExt.indexOf(ext) === -1) { diff --git a/packages/webpack/package.json b/packages/webpack/package.json index 2a8f01918..cd4454472 100644 --- a/packages/webpack/package.json +++ b/packages/webpack/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/webpack", - "version": "4.0.1", + "version": "4.1.0", "main": "index", "description": "Webpack plugin for NativeScript", "homepage": "https://nativescript.org", diff --git a/packages/webpack/templates/webpack.angular.js b/packages/webpack/templates/webpack.angular.js index 1472428ae..d9ba22b4e 100644 --- a/packages/webpack/templates/webpack.angular.js +++ b/packages/webpack/templates/webpack.angular.js @@ -4,450 +4,372 @@ const fs = require('fs'); const webpack = require('webpack'); const nsWebpack = require('@nativescript/webpack'); const nativescriptTarget = require('@nativescript/webpack/nativescript-target'); -const { - nsSupportHmrNg -} = require('@nativescript/webpack/transformers/ns-support-hmr-ng'); -const { nsTransformNativeClassesNg } = require("@nativescript/webpack/transformers/ns-transform-native-classes-ng"); -const { - parseWorkspaceConfig, hasConfigurations -} = require('@nativescript/webpack/helpers/angular-config-parser'); -const { - getMainModulePath -} = require('@nativescript/webpack/utils/ast-utils'); -const { getNoEmitOnErrorFromTSConfig, getCompilerOptionsFromTSConfig } = require("@nativescript/webpack/utils/tsconfig-utils"); +const { nsSupportHmrNg } = require('@nativescript/webpack/transformers/ns-support-hmr-ng'); +const { nsTransformNativeClassesNg } = require('@nativescript/webpack/transformers/ns-transform-native-classes-ng'); +const { parseWorkspaceConfig, hasConfigurations } = require('@nativescript/webpack/helpers/angular-config-parser'); +const { getMainModulePath } = require('@nativescript/webpack/utils/ast-utils'); +const { getNoEmitOnErrorFromTSConfig, getCompilerOptionsFromTSConfig } = require('@nativescript/webpack/utils/tsconfig-utils'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); -const { - NativeScriptWorkerPlugin -} = require('nativescript-worker-loader/NativeScriptWorkerPlugin'); +const { NativeScriptWorkerPlugin } = require('nativescript-worker-loader/NativeScriptWorkerPlugin'); const TerserPlugin = require('terser-webpack-plugin'); -const { - getAngularCompilerPlugin -} = require('@nativescript/webpack/plugins/NativeScriptAngularCompilerPlugin'); +const { getAngularCompilerPlugin } = require('@nativescript/webpack/plugins/NativeScriptAngularCompilerPlugin'); const hashSalt = Date.now().toString(); -module.exports = env => { - // Add your custom Activities, Services and other Android app components here. - const appComponents = [ - "@nativescript/core/ui/frame", "@nativescript/core/ui/frame/activity" - ]; +module.exports = (env) => { + const platform = env && ((env.android && 'android') || (env.ios && 'ios')); + if (!platform) { + throw new Error('You need to provide a target platform!'); + } - const platform = env && ((env.android && 'android') || (env.ios && 'ios')); - if (!platform) { - throw new Error('You need to provide a target platform!'); - } + const AngularCompilerPlugin = getAngularCompilerPlugin(platform); + const projectRoot = __dirname; - const AngularCompilerPlugin = getAngularCompilerPlugin(platform); - const projectRoot = __dirname; + // Default destination inside platforms//... + const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot)); - // Default destination inside platforms//... - const dist = resolve( - projectRoot, - nsWebpack.getAppPath(platform, projectRoot) - ); + const { + // The 'appPath' and 'appResourcesPath' values are fetched from + // the nsconfig.json configuration file + // when bundling with `tns run android|ios --bundle`. + appPath = 'src', + appResourcesPath = 'App_Resources', - const { - // The 'appPath' and 'appResourcesPath' values are fetched from - // the nsconfig.json configuration file - // when bundling with `tns run android|ios --bundle`. - appPath = 'src', - appResourcesPath = 'App_Resources', + // You can provide the following flags when running 'tns run android|ios' + snapshot, // --env.snapshot, + production, // --env.production + configuration, // --env.configuration (consistent with angular cli usage) + projectName, // --env.projectName (drive configuration through angular projects) + uglify, // --env.uglify + report, // --env.report + sourceMap, // --env.sourceMap + hiddenSourceMap, // --env.hiddenSourceMap + hmr, // --env.hmr, + unitTesting, // --env.unitTesting + testing, // --env.testing + verbose, // --env.verbose + ci, // --env.ci + snapshotInDocker, // --env.snapshotInDocker + skipSnapshotTools, // --env.skipSnapshotTools + compileSnapshot, // --env.compileSnapshot + appComponents = [], + entries = {}, + } = env; - // You can provide the following flags when running 'tns run android|ios' - snapshot, // --env.snapshot, - production, // --env.production - configuration, // --env.configuration (consistent with angular cli usage) - projectName, // --env.projectName (drive configuration through angular projects) - uglify, // --env.uglify - report, // --env.report - sourceMap, // --env.sourceMap - hiddenSourceMap, // --env.hiddenSourceMap - hmr, // --env.hmr, - unitTesting, // --env.unitTesting - testing, // --env.testing - verbose, // --env.verbose - ci, // --env.ci - snapshotInDocker, // --env.snapshotInDocker - skipSnapshotTools, // --env.skipSnapshotTools - compileSnapshot // --env.compileSnapshot - } = env; + const { fileReplacements, copyReplacements } = parseWorkspaceConfig(platform, configuration, projectName); - const { fileReplacements, copyReplacements } = parseWorkspaceConfig(platform, configuration, projectName); + const useLibs = compileSnapshot; + const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; + const externals = nsWebpack.getConvertedExternals(env.externals); + const appFullPath = resolve(projectRoot, appPath); + const appResourcesFullPath = resolve(projectRoot, appResourcesPath); + let tsConfigName = 'tsconfig.json'; + let tsConfigPath = resolve(projectRoot, tsConfigName); + const tsConfigTnsName = 'tsconfig.tns.json'; + const tsConfigTnsPath = resolve(projectRoot, tsConfigTnsName); + if (fs.existsSync(tsConfigTnsPath)) { + // support shared angular app configurations + tsConfigName = tsConfigTnsName; + tsConfigPath = tsConfigTnsPath; + } + const tsConfigEnvName = 'tsconfig.env.json'; + const tsConfigEnvPath = resolve(projectRoot, tsConfigEnvName); + if (hasConfigurations(configuration) && fs.existsSync(tsConfigEnvPath)) { + // when configurations are used, switch to environments supported config + tsConfigName = tsConfigEnvName; + tsConfigPath = tsConfigEnvPath; + } + const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`; + const entryPath = `.${sep}${entryModule}`; + Object.assign(entries, { bundle: entryPath }, entries); + const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some((e) => e.indexOf('@nativescript') > -1); + if (platform === 'ios' && !areCoreModulesExternal && !testing) { + entries['tns_modules/inspector_modules'] = '@nativescript/core/inspector_modules'; + } - const useLibs = compileSnapshot; - const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; - const externals = nsWebpack.getConvertedExternals(env.externals); - const appFullPath = resolve(projectRoot, appPath); - const appResourcesFullPath = resolve(projectRoot, appResourcesPath); - let tsConfigName = 'tsconfig.json'; - let tsConfigPath = resolve(projectRoot, tsConfigName); - const tsConfigTnsName = 'tsconfig.tns.json'; - const tsConfigTnsPath = resolve(projectRoot, tsConfigTnsName); - if (fs.existsSync(tsConfigTnsPath)) { - // support shared angular app configurations - tsConfigName = tsConfigTnsName; - tsConfigPath = tsConfigTnsPath; - } - const tsConfigEnvName = 'tsconfig.env.json'; - const tsConfigEnvPath = resolve(projectRoot, tsConfigEnvName); - if (hasConfigurations(configuration) && fs.existsSync(tsConfigEnvPath)) { - // when configurations are used, switch to environments supported config - tsConfigName = tsConfigEnvName; - tsConfigPath = tsConfigEnvPath; - } - const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`; - const entryPath = `.${sep}${entryModule}`; - const entries = { bundle: entryPath }; - const areCoreModulesExternal = - Array.isArray(env.externals) && - env.externals.some(e => e.indexOf('@nativescript') > -1); - if (platform === 'ios' && !areCoreModulesExternal && !testing) { - entries['tns_modules/@nativescript/core/inspector_modules'] = - 'inspector_modules'; - } + const compilerOptions = getCompilerOptionsFromTSConfig(tsConfigPath); + nsWebpack.processTsPathsForScopedModules({ compilerOptions }); + nsWebpack.processTsPathsForScopedAngular({ compilerOptions }); - const compilerOptions = getCompilerOptionsFromTSConfig(tsConfigPath); - nsWebpack.processTsPathsForScopedModules({ compilerOptions }); - nsWebpack.processTsPathsForScopedAngular({ compilerOptions }); + const ngCompilerTransformers = [nsTransformNativeClassesNg]; + const additionalLazyModuleResources = []; - const ngCompilerTransformers = [nsTransformNativeClassesNg]; - const additionalLazyModuleResources = []; + const copyIgnore = { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }; + const copyTargets = [{ from: { glob: 'assets/**', dot: false } }, { from: { glob: 'fonts/**', dot: false } }, ...copyReplacements]; - const copyIgnore = { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }; - const copyTargets = [ - { from: { glob: 'assets/**', dot: false } }, - { from: { glob: 'fonts/**', dot: false } }, - ...copyReplacements, - ]; + if (!production) { + // for development purposes only + // for example, include mock json folder + // copyTargets.push({ from: 'tools/mockdata', to: 'assets/mockdata' }); - if (!production) { - // for development purposes only - // for example, include mock json folder - // copyTargets.push({ from: 'tools/mockdata', to: 'assets/mockdata' }); + if (hmr) { + ngCompilerTransformers.push(nsSupportHmrNg); + } + } - if (hmr) { - ngCompilerTransformers.push(nsSupportHmrNg); - } - } + // when "@angular/core" is external, it's not included in the bundles. In this way, it will be used + // directly from node_modules and the Angular modules loader won't be able to resolve the lazy routes + // fixes https://github.com/NativeScript/nativescript-cli/issues/4024 + if (env.externals && env.externals.indexOf('@angular/core') > -1) { + const appModuleRelativePath = getMainModulePath(resolve(appFullPath, entryModule), tsConfigName); + if (appModuleRelativePath) { + const appModuleFolderPath = dirname(resolve(appFullPath, appModuleRelativePath)); + // include the new lazy loader path in the allowed ones + additionalLazyModuleResources.push(appModuleFolderPath); + } + } - // when "@angular/core" is external, it's not included in the bundles. In this way, it will be used - // directly from node_modules and the Angular modules loader won't be able to resolve the lazy routes - // fixes https://github.com/NativeScript/nativescript-cli/issues/4024 - if (env.externals && env.externals.indexOf('@angular/core') > -1) { - const appModuleRelativePath = getMainModulePath( - resolve(appFullPath, entryModule), - tsConfigName - ); - if (appModuleRelativePath) { - const appModuleFolderPath = dirname( - resolve(appFullPath, appModuleRelativePath) - ); - // include the new lazy loader path in the allowed ones - additionalLazyModuleResources.push(appModuleFolderPath); - } - } + const ngCompilerPlugin = new AngularCompilerPlugin({ + hostReplacementPaths: nsWebpack.getResolver([platform, 'tns']), + platformTransformers: ngCompilerTransformers.map((t) => t(() => ngCompilerPlugin, resolve(appFullPath, entryModule), projectRoot)), + mainPath: join(appFullPath, entryModule), + tsConfigPath, + skipCodeGeneration: false, + sourceMap: !!isAnySourceMapEnabled, + additionalLazyModuleResources: additionalLazyModuleResources, + compilerOptions: { paths: compilerOptions.paths }, + }); - const ngCompilerPlugin = new AngularCompilerPlugin({ - hostReplacementPaths: nsWebpack.getResolver([platform, 'tns']), - platformTransformers: ngCompilerTransformers.map(t => - t(() => ngCompilerPlugin, resolve(appFullPath, entryModule), projectRoot) - ), - mainPath: join(appFullPath, entryModule), - tsConfigPath, - skipCodeGeneration: false, - sourceMap: !!isAnySourceMapEnabled, - additionalLazyModuleResources: additionalLazyModuleResources, - compilerOptions: { paths: compilerOptions.paths } - }); + let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); - let sourceMapFilename = nsWebpack.getSourceMapFilename( - hiddenSourceMap, - __dirname, - dist - ); + const itemsToClean = [`${dist}/**/*`]; + if (platform === 'android') { + itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'src', 'main', 'assets', 'snapshots')}`); + itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'build', 'configurations', 'nativescript-android-snapshot')}`); + } - const itemsToClean = [`${dist}/**/*`]; - if (platform === 'android') { - itemsToClean.push( - `${join( - projectRoot, - 'platforms', - 'android', - 'app', - 'src', - 'main', - 'assets', - 'snapshots' - )}` - ); - itemsToClean.push( - `${join( - projectRoot, - 'platforms', - 'android', - 'app', - 'build', - 'configurations', - 'nativescript-android-snapshot' - )}` - ); - } + const noEmitOnErrorFromTSConfig = getNoEmitOnErrorFromTSConfig(tsConfigName); - const noEmitOnErrorFromTSConfig = getNoEmitOnErrorFromTSConfig(tsConfigName); + // Add your custom Activities, Services and other android app components here. + appComponents.push('@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity'); - nsWebpack.processAppComponents(appComponents, platform); - const config = { - mode: production ? 'production' : 'development', - context: appFullPath, - externals, - watchOptions: { - ignored: [ - appResourcesFullPath, - // Don't watch hidden files - '**/.*' - ] - }, - target: nativescriptTarget, - entry: entries, - output: { - pathinfo: false, - path: dist, - sourceMapFilename, - libraryTarget: 'commonjs2', - filename: '[name].js', - globalObject: 'global', - hashSalt - }, - resolve: { - extensions: ['.ts', '.js', '.scss', '.css'], - // Resolve {N} system modules from @nativescript/core - modules: [ - resolve(__dirname, 'node_modules/@nativescript/core'), - resolve(__dirname, 'node_modules'), - 'node_modules/@nativescript/core', - 'node_modules' - ], - alias: { - '~/package.json': resolve(projectRoot, 'package.json'), - '~': appFullPath, - "tns-core-modules": "@nativescript/core", - "nativescript-angular": "@nativescript/angular", - ...fileReplacements - }, - symlinks: true - }, - resolveLoader: { - symlinks: false - }, - node: { - // Disable node shims that conflict with NativeScript - http: false, - timers: false, - setImmediate: false, - fs: 'empty', - __dirname: false - }, - devtool: hiddenSourceMap - ? 'hidden-source-map' - : sourceMap - ? 'inline-source-map' - : 'none', - optimization: { - runtimeChunk: 'single', - noEmitOnErrors: noEmitOnErrorFromTSConfig, - splitChunks: { - cacheGroups: { - vendor: { - name: 'vendor', - chunks: 'all', - test: (module, chunks) => { - const moduleName = module.nameForCondition - ? module.nameForCondition() - : ''; - return ( - /[\\/]node_modules[\\/]/.test(moduleName) || - appComponents.some(comp => comp === moduleName) - ); - }, - enforce: true - } - } - }, - minimize: !!uglify, - minimizer: [ - new TerserPlugin({ - parallel: true, - cache: !ci, - sourceMap: isAnySourceMapEnabled, - terserOptions: { - output: { - comments: false, - semicolons: !isAnySourceMapEnabled - }, - compress: { - // The Android SBG has problems parsing the output - // when these options are enabled - collapse_vars: platform !== 'android', - sequences: platform !== 'android', - // custom - drop_console: true, - drop_debugger: true, - ecma: 6, - keep_infinity: platform === 'android', // for Chrome/V8 - reduce_funcs: platform !== 'android', // for Chrome/V8 - global_defs: { - __UGLIFIED__: true - } - }, - // custom - ecma: 6, - safari10: platform !== 'android' - } - }) - ] - }, - module: { - rules: [ - { - include: join(appFullPath, entryPath), - use: [ - // Require all Android app components - platform === 'android' && { - loader: '@nativescript/webpack/helpers/android-app-components-loader', - options: { modules: appComponents } - }, + nsWebpack.processAppComponents(appComponents, platform); + const config = { + mode: production ? 'production' : 'development', + context: appFullPath, + externals, + watchOptions: { + ignored: [ + appResourcesFullPath, + // Don't watch hidden files + '**/.*', + ], + }, + target: nativescriptTarget, + entry: entries, + output: { + pathinfo: false, + path: dist, + sourceMapFilename, + libraryTarget: 'commonjs2', + filename: '[name].js', + globalObject: 'global', + hashSalt, + }, + resolve: { + extensions: ['.ts', '.js', '.scss', '.css'], + // Resolve {N} system modules from @nativescript/core + modules: [resolve(__dirname, 'node_modules/@nativescript/core'), resolve(__dirname, 'node_modules'), 'node_modules/@nativescript/core', 'node_modules'], + alias: { + '~/package.json': resolve(projectRoot, 'package.json'), + '~': appFullPath, + 'tns-core-modules': '@nativescript/core', + 'nativescript-angular': '@nativescript/angular', + ...fileReplacements, + }, + symlinks: true, + }, + resolveLoader: { + symlinks: false, + }, + node: { + // Disable node shims that conflict with NativeScript + http: false, + timers: false, + setImmediate: false, + fs: 'empty', + __dirname: false, + }, + devtool: hiddenSourceMap ? 'hidden-source-map' : sourceMap ? 'inline-source-map' : 'none', + optimization: { + runtimeChunk: 'single', + noEmitOnErrors: noEmitOnErrorFromTSConfig, + splitChunks: { + cacheGroups: { + vendor: { + name: 'vendor', + chunks: 'all', + test: (module, chunks) => { + const moduleName = module.nameForCondition ? module.nameForCondition() : ''; + return /[\\/]node_modules[\\/]/.test(moduleName) || appComponents.some((comp) => comp === moduleName); + }, + enforce: true, + }, + }, + }, + minimize: !!uglify, + minimizer: [ + new TerserPlugin({ + parallel: true, + cache: !ci, + sourceMap: isAnySourceMapEnabled, + terserOptions: { + output: { + comments: false, + semicolons: !isAnySourceMapEnabled, + }, + compress: { + // The Android SBG has problems parsing the output + // when these options are enabled + collapse_vars: platform !== 'android', + sequences: platform !== 'android', + // For v8 Compatibility + keep_infinity: true, // for V8 + reduce_funcs: false, // for V8 + // custom + drop_console: production, + drop_debugger: true, + ecma: 6, + global_defs: { + __UGLIFIED__: true, + }, + }, + // Required for Element Level CSS, Observable Events, & Android Frame + keep_classnames: true, + // custom + ecma: 6, + safari10: platform !== 'android', + }, + }), + ], + }, + module: { + rules: [ + { + include: join(appFullPath, entryPath), + use: [ + // Require all Android app components + platform === 'android' && { + loader: '@nativescript/webpack/helpers/android-app-components-loader', + options: { modules: appComponents }, + }, - { - loader: '@nativescript/webpack/bundle-config-loader', - options: { - angular: true, - loadCss: !snapshot, // load the application css if in debug mode - unitTesting, - appFullPath, - projectRoot, - ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) - } - } - ].filter(loader => !!loader) - }, + { + loader: '@nativescript/webpack/bundle-config-loader', + options: { + angular: true, + loadCss: !snapshot, // load the application css if in debug mode + unitTesting, + appFullPath, + projectRoot, + ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform), + }, + }, + ].filter((loader) => !!loader), + }, - { test: /\.html$|\.xml$/, use: 'raw-loader' }, + { test: /\.html$|\.xml$/, use: 'raw-loader' }, - { - test: /[\/|\\]app\.css$/, - use: [ - '@nativescript/webpack/helpers/style-hot-loader', - { - loader: "@nativescript/webpack/helpers/css2json-loader", - options: { useForImports: true } - }, - ], - }, - { - test: /[\/|\\]app\.scss$/, - use: [ - '@nativescript/webpack/helpers/style-hot-loader', - { - loader: "@nativescript/webpack/helpers/css2json-loader", - options: { useForImports: true } - }, - 'sass-loader', - ], - }, + { + test: /[\/|\\]app\.css$/, + use: [ + '@nativescript/webpack/helpers/style-hot-loader', + { + loader: '@nativescript/webpack/helpers/css2json-loader', + options: { useForImports: true }, + }, + ], + }, + { + test: /[\/|\\]app\.scss$/, + use: [ + '@nativescript/webpack/helpers/style-hot-loader', + { + loader: '@nativescript/webpack/helpers/css2json-loader', + options: { useForImports: true }, + }, + 'sass-loader', + ], + }, - // Angular components reference css files and their imports using raw-loader - { test: /\.css$/, exclude: /[\/|\\]app\.css$/, use: 'raw-loader' }, - { - test: /\.scss$/, - exclude: /[\/|\\]app\.scss$/, - use: ['raw-loader', 'resolve-url-loader', 'sass-loader'] - }, + // Angular components reference css files and their imports using raw-loader + { test: /\.css$/, exclude: /[\/|\\]app\.css$/, use: 'raw-loader' }, + { + test: /\.scss$/, + exclude: /[\/|\\]app\.scss$/, + use: ['raw-loader', 'resolve-url-loader', 'sass-loader'], + }, - { - test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, - use: [ - '@nativescript/webpack/helpers/moduleid-compat-loader', - '@nativescript/webpack/helpers/lazy-ngmodule-hot-loader', - '@ngtools/webpack' - ] - }, + { + test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, + use: ['@nativescript/webpack/helpers/moduleid-compat-loader', '@nativescript/webpack/helpers/lazy-ngmodule-hot-loader', '@ngtools/webpack'], + }, - // Mark files inside `@angular/core` as using SystemJS style dynamic imports. - // Removing this will cause deprecation warnings to appear. - { - test: /[\/\\]@angular[\/\\]core[\/\\].+\.js$/, - parser: { system: true } - } - ] - }, - plugins: [ - // Define useful constants like TNS_WEBPACK - new webpack.DefinePlugin({ - 'global.TNS_WEBPACK': 'true', - 'global.isAndroid': platform === 'android', - 'global.isIOS': platform === 'ios', - process: 'global.process' - }), - // Remove all files from the out dir. - new CleanWebpackPlugin({ - cleanOnceBeforeBuildPatterns: itemsToClean, - verbose: !!verbose - }), - // Copy assets - new CopyWebpackPlugin([ - ...copyTargets, - { from: { glob: '**/*.jpg', dot: false } }, - { from: { glob: '**/*.png', dot: false } }, - ], copyIgnore), - new nsWebpack.GenerateNativeScriptEntryPointsPlugin('bundle'), - // For instructions on how to set up workers with webpack - // check out https://github.com/nativescript/worker-loader - new NativeScriptWorkerPlugin(), - ngCompilerPlugin, - // Does IPC communication with the {N} CLI to notify events when running in watch mode. - new nsWebpack.WatchStateLoggerPlugin() - ] - }; + // Mark files inside `@angular/core` as using SystemJS style dynamic imports. + // Removing this will cause deprecation warnings to appear. + { + test: /[\/\\]@angular[\/\\]core[\/\\].+\.js$/, + parser: { system: true }, + }, + ], + }, + plugins: [ + // Define useful constants like TNS_WEBPACK + new webpack.DefinePlugin({ + 'global.TNS_WEBPACK': 'true', + 'global.isAndroid': platform === 'android', + 'global.isIOS': platform === 'ios', + process: 'global.process', + }), + // Remove all files from the out dir. + new CleanWebpackPlugin({ + cleanOnceBeforeBuildPatterns: itemsToClean, + verbose: !!verbose, + }), + // Copy assets + new CopyWebpackPlugin([...copyTargets, { from: { glob: '**/*.jpg', dot: false } }, { from: { glob: '**/*.png', dot: false } }], copyIgnore), + new nsWebpack.GenerateNativeScriptEntryPointsPlugin('bundle'), + // For instructions on how to set up workers with webpack + // check out https://github.com/nativescript/worker-loader + new NativeScriptWorkerPlugin(), + ngCompilerPlugin, + // Does IPC communication with the {N} CLI to notify events when running in watch mode. + new nsWebpack.WatchStateLoggerPlugin(), + ], + }; - if (report) { - // Generate report files for bundles content - config.plugins.push( - new BundleAnalyzerPlugin({ - analyzerMode: 'static', - openAnalyzer: false, - generateStatsFile: true, - reportFilename: resolve(projectRoot, 'report', `report.html`), - statsFilename: resolve(projectRoot, 'report', `stats.json`) - }) - ); - } + if (report) { + // Generate report files for bundles content + config.plugins.push( + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false, + generateStatsFile: true, + reportFilename: resolve(projectRoot, 'report', `report.html`), + statsFilename: resolve(projectRoot, 'report', `stats.json`), + }) + ); + } - if (snapshot) { - config.plugins.push( - new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: 'vendor', - angular: true, - requireModules: [ - 'reflect-metadata', - '@angular/platform-browser', - '@angular/core', - '@angular/common', - '@angular/router', - '@nativescript/angular' - ], - projectRoot, - webpackConfig: config, - snapshotInDocker, - skipSnapshotTools, - useLibs - }) - ); - } + if (snapshot) { + config.plugins.push( + new nsWebpack.NativeScriptSnapshotPlugin({ + chunk: 'vendor', + angular: true, + requireModules: ['reflect-metadata', '@angular/platform-browser', '@angular/core', '@angular/common', '@angular/router', '@nativescript/angular'], + projectRoot, + webpackConfig: config, + snapshotInDocker, + skipSnapshotTools, + useLibs, + }) + ); + } - if (!production && hmr) { - config.plugins.push(new webpack.HotModuleReplacementPlugin()); - } + if (!production && hmr) { + config.plugins.push(new webpack.HotModuleReplacementPlugin()); + } - return config; -}; \ No newline at end of file + return config; +}; diff --git a/packages/webpack/templates/webpack.javascript.js b/packages/webpack/templates/webpack.javascript.js index 69c197a69..df1a3caf5 100644 --- a/packages/webpack/templates/webpack.javascript.js +++ b/packages/webpack/templates/webpack.javascript.js @@ -1,297 +1,293 @@ -const { join, relative, resolve, sep } = require("path"); +const { join, relative, resolve, sep } = require('path'); const fs = require('fs'); -const webpack = require("webpack"); -const nsWebpack = require("@nativescript/webpack"); -const nativescriptTarget = require("@nativescript/webpack/nativescript-target"); -const { CleanWebpackPlugin } = require("clean-webpack-plugin"); -const CopyWebpackPlugin = require("copy-webpack-plugin"); -const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); -const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); -const TerserPlugin = require("terser-webpack-plugin"); +const webpack = require('webpack'); +const nsWebpack = require('@nativescript/webpack'); +const nativescriptTarget = require('@nativescript/webpack/nativescript-target'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); +const { NativeScriptWorkerPlugin } = require('nativescript-worker-loader/NativeScriptWorkerPlugin'); +const TerserPlugin = require('terser-webpack-plugin'); const hashSalt = Date.now().toString(); -module.exports = env => { - // Add your custom Activities, Services and other android app components here. - const appComponents = env.appComponents || []; - appComponents.push(...[ - "@nativescript/core/ui/frame", - "@nativescript/core/ui/frame/activity", - ]); +module.exports = (env) => { + const platform = env && ((env.android && 'android') || (env.ios && 'ios') || env.platform); + if (!platform) { + throw new Error('You need to provide a target platform!'); + } - const platform = env && (env.android && "android" || env.ios && "ios" || env.platform); - if (!platform) { - throw new Error("You need to provide a target platform!"); - } + const platforms = ['ios', 'android']; + const projectRoot = __dirname; - const platforms = ["ios", "android"]; - const projectRoot = __dirname; + if (env.platform) { + platforms.push(env.platform); + } - if (env.platform) { - platforms.push(env.platform); - } + // Default destination inside platforms//... + const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot)); - // Default destination inside platforms//... - const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot)); + const { + // The 'appPath' and 'appResourcesPath' values are fetched from + // the nsconfig.json configuration file. + appPath = 'src', + appResourcesPath = 'App_Resources', - const { - // The 'appPath' and 'appResourcesPath' values are fetched from - // the nsconfig.json configuration file. - appPath = "src", - appResourcesPath = "App_Resources", + // You can provide the following flags when running 'tns run android|ios' + snapshot, // --env.snapshot + production, // --env.production + uglify, // --env.uglify + report, // --env.report + sourceMap, // --env.sourceMap + hiddenSourceMap, // --env.hiddenSourceMap + hmr, // --env.hmr, + unitTesting, // --env.unitTesting, + testing, // --env.testing + verbose, // --env.verbose + snapshotInDocker, // --env.snapshotInDocker + skipSnapshotTools, // --env.skipSnapshotTools + ci, // --env.ci + compileSnapshot, // --env.compileSnapshot + appComponents = [], + entries = {}, + } = env; - // You can provide the following flags when running 'tns run android|ios' - snapshot, // --env.snapshot - production, // --env.production - uglify, // --env.uglify - report, // --env.report - sourceMap, // --env.sourceMap - hiddenSourceMap, // --env.hiddenSourceMap - hmr, // --env.hmr, - unitTesting, // --env.unitTesting, - testing, // --env.testing - verbose, // --env.verbose - snapshotInDocker, // --env.snapshotInDocker - skipSnapshotTools, // --env.skipSnapshotTools - compileSnapshot // --env.compileSnapshot - } = env; + const useLibs = compileSnapshot; + const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; + const externals = nsWebpack.getConvertedExternals(env.externals); - const useLibs = compileSnapshot; - const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; - const externals = nsWebpack.getConvertedExternals(env.externals); - let appFullPath = resolve(projectRoot, appPath); - if (!fs.existsSync(appFullPath)) { - // some apps use 'app' directory - appFullPath = resolve(projectRoot, 'app'); - } - const hasRootLevelScopedModules = nsWebpack.hasRootLevelScopedModules({ projectDir: projectRoot }); - let coreModulesPackageName = "tns-core-modules"; - const alias = env.alias || {}; - alias['~/package.json'] = resolve(projectRoot, 'package.json'); - alias['~'] = appFullPath; + let appFullPath = resolve(projectRoot, appPath); + if (!fs.existsSync(appFullPath)) { + // some apps use 'app' directory + appFullPath = resolve(projectRoot, 'app'); + } + const hasRootLevelScopedModules = nsWebpack.hasRootLevelScopedModules({ projectDir: projectRoot }); + let coreModulesPackageName = 'tns-core-modules'; + const alias = env.alias || {}; + alias['~/package.json'] = resolve(projectRoot, 'package.json'); + alias['~'] = appFullPath; - if (hasRootLevelScopedModules) { - coreModulesPackageName = "@nativescript/core"; - alias["tns-core-modules"] = coreModulesPackageName; - } - const appResourcesFullPath = resolve(projectRoot, appResourcesPath); + if (hasRootLevelScopedModules) { + coreModulesPackageName = '@nativescript/core'; + alias['tns-core-modules'] = coreModulesPackageName; + } + const appResourcesFullPath = resolve(projectRoot, appResourcesPath); - const copyIgnore = { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }; + const copyIgnore = { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }; - const entryModule = nsWebpack.getEntryModule(appFullPath, platform); - const entryPath = `.${sep}${entryModule}.js`; - const entries = env.entries || {}; - entries.bundle = entryPath; + const entryModule = nsWebpack.getEntryModule(appFullPath, platform); + const entryPath = `.${sep}${entryModule}.js`; + Object.assign(entries, { bundle: entryPath }, entries); - const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some(e => e.indexOf("@nativescript") > -1); - if (platform === "ios" && !areCoreModulesExternal && !testing) { - entries["tns_modules/@nativescript/core/inspector_modules"] = "inspector_modules"; - }; + const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some((e) => e.indexOf('@nativescript') > -1); + if (platform === 'ios' && !areCoreModulesExternal && !testing) { + entries['tns_modules/inspector_modules'] = '@nativescript/core/inspector_modules'; + } - let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); - const itemsToClean = [`${dist}/**/*`]; - if (platform === "android") { - itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); - itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); - } + const itemsToClean = [`${dist}/**/*`]; + if (platform === 'android') { + itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'src', 'main', 'assets', 'snapshots')}`); + itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'build', 'configurations', 'nativescript-android-snapshot')}`); + } + // Add your custom Activities, Services and other android app components here. + appComponents.push('@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity'); - nsWebpack.processAppComponents(appComponents, platform); - const config = { - mode: production ? "production" : "development", - context: appFullPath, - externals, - watchOptions: { - ignored: [ - appResourcesFullPath, - // Don't watch hidden files - "**/.*", - ] - }, - target: nativescriptTarget, - entry: entries, - output: { - pathinfo: false, - path: dist, - sourceMapFilename, - libraryTarget: "commonjs2", - filename: "[name].js", - globalObject: "global", - hashSalt - }, - resolve: { - extensions: [".js", ".scss", ".css"], - // Resolve {N} system modules from @nativescript/core - modules: [ - resolve(__dirname, `node_modules/${coreModulesPackageName}`), - resolve(__dirname, "node_modules"), - `node_modules/${coreModulesPackageName}`, - "node_modules", - ], - alias, - // resolve symlinks to symlinked modules - symlinks: true - }, - resolveLoader: { - // don't resolve symlinks to symlinked loaders - symlinks: false - }, - node: { - // Disable node shims that conflict with NativeScript - "http": false, - "timers": false, - "setImmediate": false, - "fs": "empty", - "__dirname": false, - }, - devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"), - optimization: { - runtimeChunk: "single", - noEmitOnErrors: true, - splitChunks: { - cacheGroups: { - vendor: { - name: "vendor", - chunks: "all", - test: (module, chunks) => { - const moduleName = module.nameForCondition ? module.nameForCondition() : ''; - return /[\\/]node_modules[\\/]/.test(moduleName) || - appComponents.some(comp => comp === moduleName); + nsWebpack.processAppComponents(appComponents, platform); + const config = { + mode: production ? 'production' : 'development', + context: appFullPath, + externals, + watchOptions: { + ignored: [ + appResourcesFullPath, + // Don't watch hidden files + '**/.*', + ], + }, + target: nativescriptTarget, + entry: entries, + output: { + pathinfo: false, + path: dist, + sourceMapFilename, + libraryTarget: 'commonjs2', + filename: '[name].js', + globalObject: 'global', + hashSalt, + }, + resolve: { + extensions: ['.js', '.scss', '.css'], + // Resolve {N} system modules from @nativescript/core + modules: [resolve(__dirname, `node_modules/${coreModulesPackageName}`), resolve(__dirname, 'node_modules'), `node_modules/${coreModulesPackageName}`, 'node_modules'], + alias, + // resolve symlinks to symlinked modules + symlinks: true, + }, + resolveLoader: { + // don't resolve symlinks to symlinked loaders + symlinks: false, + }, + node: { + // Disable node shims that conflict with NativeScript + http: false, + timers: false, + setImmediate: false, + fs: 'empty', + __dirname: false, + }, + devtool: hiddenSourceMap ? 'hidden-source-map' : sourceMap ? 'inline-source-map' : 'none', + optimization: { + runtimeChunk: 'single', + noEmitOnErrors: true, + splitChunks: { + cacheGroups: { + vendor: { + name: 'vendor', + chunks: 'all', + test: (module, chunks) => { + const moduleName = module.nameForCondition ? module.nameForCondition() : ''; + return /[\\/]node_modules[\\/]/.test(moduleName) || appComponents.some((comp) => comp === moduleName); + }, + enforce: true, + }, + }, + }, + minimize: !!uglify, + minimizer: [ + new TerserPlugin({ + parallel: true, + cache: !ci, + sourceMap: isAnySourceMapEnabled, + terserOptions: { + output: { + comments: false, + semicolons: !isAnySourceMapEnabled, + }, + compress: { + // The Android SBG has problems parsing the output + // when these options are enabled + collapse_vars: platform !== 'android', + sequences: platform !== 'android', + // For v8 Compatibility + keep_infinity: true, // for V8 + reduce_funcs: false, // for V8 + // custom + drop_console: production, + drop_debugger: true, + global_defs: { + __UGLIFIED__: true, + }, + }, + // Required for Element Level CSS, Observable Events, & Android Frame + keep_classnames: true, + }, + }), + ], + }, + module: { + rules: [ + { + include: join(appFullPath, entryPath), + use: [ + // Require all Android app components + platform === 'android' && { + loader: '@nativescript/webpack/helpers/android-app-components-loader', + options: { modules: appComponents }, + }, - }, - enforce: true, - }, - } - }, - minimize: !!uglify, - minimizer: [ - new TerserPlugin({ - parallel: true, - cache: true, - sourceMap: isAnySourceMapEnabled, - terserOptions: { - output: { - comments: false, - semicolons: !isAnySourceMapEnabled - }, - compress: { - // The Android SBG has problems parsing the output - // when these options are enabled - 'collapse_vars': platform !== "android", - sequences: platform !== "android", - } - } - }) - ], - }, - module: { - rules: [ - { - include: join(appFullPath, entryPath), - use: [ - // Require all Android app components - platform === "android" && { - loader: "@nativescript/webpack/helpers/android-app-components-loader", - options: { modules: appComponents } - }, + { + loader: '@nativescript/webpack/bundle-config-loader', + options: { + loadCss: !snapshot, // load the application css if in debug mode + unitTesting, + appFullPath, + projectRoot, + ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform), + }, + }, + ].filter((loader) => !!loader), + }, - { - loader: "@nativescript/webpack/bundle-config-loader", - options: { - loadCss: !snapshot, // load the application css if in debug mode - unitTesting, - appFullPath, - projectRoot, - ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) - } - }, - ].filter(loader => !!loader) - }, + { + test: /\.(js|css|scss|html|xml)$/, + use: '@nativescript/webpack/hmr/hot-loader', + }, - { - test: /\.(js|css|scss|html|xml)$/, - use: "@nativescript/webpack/hmr/hot-loader" - }, + { test: /\.(html|xml)$/, use: '@nativescript/webpack/helpers/xml-namespace-loader' }, - { test: /\.(html|xml)$/, use: "@nativescript/webpack/helpers/xml-namespace-loader" }, + { + test: /\.css$/, + use: '@nativescript/webpack/helpers/css2json-loader', + }, - { - test: /\.css$/, - use: "@nativescript/webpack/helpers/css2json-loader" - }, + { + test: /\.scss$/, + use: ['@nativescript/webpack/helpers/css2json-loader', 'sass-loader'], + }, + ], + }, + plugins: [ + // Define useful constants like TNS_WEBPACK + new webpack.DefinePlugin({ + 'global.TNS_WEBPACK': 'true', + 'global.isAndroid': platform === 'android', + 'global.isIOS': platform === 'ios', + process: 'global.process', + }), + // Remove all files from the out dir. + new CleanWebpackPlugin({ + cleanOnceBeforeBuildPatterns: itemsToClean, + verbose: !!verbose, + }), + // Copy assets + new CopyWebpackPlugin([{ from: { glob: 'assets/**', dot: false } }, { from: { glob: 'fonts/**', dot: false } }, { from: { glob: '**/*.jpg', dot: false } }, { from: { glob: '**/*.png', dot: false } }], copyIgnore), + new nsWebpack.GenerateNativeScriptEntryPointsPlugin('bundle'), - { - test: /\.scss$/, - use: [ - "@nativescript/webpack/helpers/css2json-loader", - "sass-loader" - ] - }, - ] - }, - plugins: [ - // Define useful constants like TNS_WEBPACK - new webpack.DefinePlugin({ - "global.TNS_WEBPACK": "true", - "global.isAndroid": platform === 'android', - "global.isIOS": platform === 'ios', - "process": "global.process", - }), - // Remove all files from the out dir. - new CleanWebpackPlugin({ - cleanOnceBeforeBuildPatterns: itemsToClean, - verbose: !!verbose - }), - // Copy assets - new CopyWebpackPlugin([ - { from: { glob: 'assets/**', dot: false } }, - { from: { glob: 'fonts/**', dot: false } }, - { from: { glob: '**/*.jpg', dot: false } }, - { from: { glob: '**/*.png', dot: false } }, - ], copyIgnore), - new nsWebpack.GenerateNativeScriptEntryPointsPlugin("bundle"), + // For instructions on how to set up workers with webpack + // check out https://github.com/nativescript/worker-loader + new NativeScriptWorkerPlugin(), + new nsWebpack.PlatformFSPlugin({ + platform, + platforms, + }), + // Does IPC communication with the {N} CLI to notify events when running in watch mode. + new nsWebpack.WatchStateLoggerPlugin(), + ], + }; - // For instructions on how to set up workers with webpack - // check out https://github.com/nativescript/worker-loader - new NativeScriptWorkerPlugin(), - new nsWebpack.PlatformFSPlugin({ - platform, - platforms, - }), - // Does IPC communication with the {N} CLI to notify events when running in watch mode. - new nsWebpack.WatchStateLoggerPlugin() - ], - }; + if (report) { + // Generate report files for bundles content + config.plugins.push( + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false, + generateStatsFile: true, + reportFilename: resolve(projectRoot, 'report', `report.html`), + statsFilename: resolve(projectRoot, 'report', `stats.json`), + }) + ); + } - if (report) { - // Generate report files for bundles content - config.plugins.push(new BundleAnalyzerPlugin({ - analyzerMode: "static", - openAnalyzer: false, - generateStatsFile: true, - reportFilename: resolve(projectRoot, "report", `report.html`), - statsFilename: resolve(projectRoot, "report", `stats.json`), - })); - } + if (snapshot) { + config.plugins.push( + new nsWebpack.NativeScriptSnapshotPlugin({ + chunk: 'vendor', + requireModules: ['@nativescript/core/bundle-entry-points'], + projectRoot, + webpackConfig: config, + snapshotInDocker, + skipSnapshotTools, + useLibs, + }) + ); + } - if (snapshot) { - config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "vendor", - requireModules: [ - "@nativescript/core/bundle-entry-points", - ], - projectRoot, - webpackConfig: config, - snapshotInDocker, - skipSnapshotTools, - useLibs - })); - } + if (hmr) { + config.plugins.push(new webpack.HotModuleReplacementPlugin()); + } - if (hmr) { - config.plugins.push(new webpack.HotModuleReplacementPlugin()); - } - - return config; + return config; }; diff --git a/packages/webpack/templates/webpack.react.js b/packages/webpack/templates/webpack.react.js index d9c3f9062..ebd0f4d52 100644 --- a/packages/webpack/templates/webpack.react.js +++ b/packages/webpack/templates/webpack.react.js @@ -2,87 +2,86 @@ * @see https://github.com/NativeScript/NativeScript/tree/feat/ns7-finishing-touches/packages/webpack/templates * @see https://github.com/NativeScript/NativeScript/pull/8801/files */ -const webpackConfig = require("./webpack.typescript"); -const webpack = require("webpack"); +const webpackConfig = require('./webpack.typescript'); +const webpack = require('webpack'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); module.exports = (env) => { - env = env || {}; - const hmr = env.hmr; - const production = env.production; - const isAnySourceMapEnabled = !!env.sourceMap || !!env.hiddenSourceMap; + env = env || {}; + const hmr = env.hmr; + const production = env.production; + const isAnySourceMapEnabled = !!env.sourceMap || !!env.hiddenSourceMap; - const baseConfig = webpackConfig(env); + const baseConfig = webpackConfig(env); - /** Find the rule for transpiling ts files ("ts-loader"), and modify it to test for .tsx files too. */ - const tsxRule = baseConfig.module.rules.find(rule => rule.use && rule.use.loader === "ts-loader"); - tsxRule.test = /\.(ts|tsx)$/; - tsxRule.use = [ - /** - * Add React Refresh HMR support. - * @see https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/55028c6355b31e697e21bf3e9a48613a7b94bee7/examples/typescript-without-babel/webpack.config.js#L18-L21 - */ - hmr && !production && { - loader: "babel-loader", - options: { - sourceMaps: isAnySourceMapEnabled ? "inline" : false, - babelrc: false, - plugins: ['react-refresh/babel'] - } - }, - tsxRule.use, - ].filter(Boolean); + /** Find the rule for transpiling ts files ("ts-loader"), and modify it to test for .tsx files too. */ + const tsxRule = baseConfig.module.rules.find((rule) => rule.use && rule.use.loader === 'ts-loader'); + tsxRule.test = /\.(ts|tsx)$/; + tsxRule.use = [ + /** + * Add React Refresh HMR support. + * @see https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/55028c6355b31e697e21bf3e9a48613a7b94bee7/examples/typescript-without-babel/webpack.config.js#L18-L21 + */ + hmr && + !production && { + loader: 'babel-loader', + options: { + sourceMaps: isAnySourceMapEnabled ? 'inline' : false, + babelrc: false, + plugins: ['react-refresh/babel'], + }, + }, + tsxRule.use, + ].filter(Boolean); - /** - * Modify "nativescript-dev-webpack/hmr/hot-loader" to test for .tsx files - * (and also js files, which it should have been doing to begin with!) - */ - const nativeScriptDevWebpackHotLoader = baseConfig.module.rules.find(rule => - rule.use === "@nativescript/webpack/hmr/hot-loader" - ); - nativeScriptDevWebpackHotLoader.test = /\.(ts|tsx|js|css|scss|html|xml)$/; + /** + * Modify "nativescript-dev-webpack/hmr/hot-loader" to test for .tsx files + * (and also js files, which it should have been doing to begin with!) + */ + const nativeScriptDevWebpackHotLoader = baseConfig.module.rules.find((rule) => rule.use === '@nativescript/webpack/hmr/hot-loader'); + nativeScriptDevWebpackHotLoader.test = /\.(ts|tsx|js|css|scss|html|xml)$/; - /** We don't officially support JSX. Makes the webpack config rather more complicated to set up. */ - baseConfig.resolve.extensions = [".tsx", ...baseConfig.resolve.extensions]; - baseConfig.resolve.alias["react-dom"] = "react-nativescript"; + /** We don't officially support JSX. Makes the webpack config rather more complicated to set up. */ + baseConfig.resolve.extensions = ['.tsx', ...baseConfig.resolve.extensions]; + baseConfig.resolve.alias['react-dom'] = 'react-nativescript'; - /** Augment NativeScript's existing DefinePlugin definitions with a few more of our own. */ - const existingDefinePlugin = baseConfig.plugins.find(plugin => - plugin && plugin.constructor && plugin.constructor.name === "DefinePlugin" - ); - baseConfig.plugins.splice( - baseConfig.plugins.indexOf(existingDefinePlugin), - 1, - new webpack.DefinePlugin({ - ...existingDefinePlugin.definitions, - /** For various libraries in the React ecosystem. */ - "__DEV__": production ? "false" : "true", - "__TEST__": "false", - /** - * Primarily for React Fast Refresh plugin, but technically the allowHmrInProduction option could be used instead. - * Worth including anyway, as there are plenty of Node libraries that use this flag. - */ - "process.env.NODE_ENV": JSON.stringify(production ? "production" : "development"), - }), - ); + /** Augment NativeScript's existing DefinePlugin definitions with a few more of our own. */ + const existingDefinePlugin = baseConfig.plugins.find((plugin) => plugin && plugin.constructor && plugin.constructor.name === 'DefinePlugin'); + baseConfig.plugins.splice( + baseConfig.plugins.indexOf(existingDefinePlugin), + 1, + new webpack.DefinePlugin({ + ...existingDefinePlugin.definitions, + /** For various libraries in the React ecosystem. */ + __DEV__: production ? 'false' : 'true', + __TEST__: 'false', + /** + * Primarily for React Fast Refresh plugin, but technically the allowHmrInProduction option could be used instead. + * Worth including anyway, as there are plenty of Node libraries that use this flag. + */ + 'process.env.NODE_ENV': JSON.stringify(production ? 'production' : 'development'), + }) + ); - if(hmr && !production){ - baseConfig.plugins.push(new ReactRefreshWebpackPlugin({ - /** - * Maybe one day we'll implement an Error Overlay, but the work involved is too daunting for now. - * @see https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/79#issuecomment-644324557 - */ - overlay: false, - /** - * If you (temporarily) want to enable HMR on a production build: - * 1) Set `forceEnable` to `true` - * 2) Remove the `!production` condition on `tsxRule` to ensure that babel-loader gets used. - */ - forceEnable: false, - })); - } else { - baseConfig.plugins = baseConfig.plugins.filter(p => !(p && p.constructor && p.constructor.name === "HotModuleReplacementPlugin")); - } + if (hmr && !production) { + baseConfig.plugins.push( + new ReactRefreshWebpackPlugin({ + /** + * Maybe one day we'll implement an Error Overlay, but the work involved is too daunting for now. + * @see https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/79#issuecomment-644324557 + */ + overlay: false, + /** + * If you (temporarily) want to enable HMR on a production build: + * 1) Set `forceEnable` to `true` + * 2) Remove the `!production` condition on `tsxRule` to ensure that babel-loader gets used. + */ + forceEnable: false, + }) + ); + } else { + baseConfig.plugins = baseConfig.plugins.filter((p) => !(p && p.constructor && p.constructor.name === 'HotModuleReplacementPlugin')); + } - return baseConfig; -}; \ No newline at end of file + return baseConfig; +}; diff --git a/packages/webpack/templates/webpack.svelte.js b/packages/webpack/templates/webpack.svelte.js index c552dbae5..756de7d8b 100644 --- a/packages/webpack/templates/webpack.svelte.js +++ b/packages/webpack/templates/webpack.svelte.js @@ -1,34 +1,27 @@ -const { join, relative, resolve, sep } = require("path"); +const { join, relative, resolve, sep } = require('path'); const fs = require('fs'); -const webpack = require("webpack"); -const nsWebpack = require("@nativescript/webpack"); -const nativescriptTarget = require("@nativescript/webpack/nativescript-target"); -const { getNoEmitOnErrorFromTSConfig } = require("@nativescript/webpack/utils/tsconfig-utils"); -const { CleanWebpackPlugin } = require("clean-webpack-plugin"); -const CopyWebpackPlugin = require("copy-webpack-plugin"); +const webpack = require('webpack'); +const nsWebpack = require('@nativescript/webpack'); +const nativescriptTarget = require('@nativescript/webpack/nativescript-target'); +const { getNoEmitOnErrorFromTSConfig } = require('@nativescript/webpack/utils/tsconfig-utils'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); -const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); -const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); -const TerserPlugin = require("terser-webpack-plugin"); +const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); +const { NativeScriptWorkerPlugin } = require('nativescript-worker-loader/NativeScriptWorkerPlugin'); +const TerserPlugin = require('terser-webpack-plugin'); const hashSalt = Date.now().toString(); -const preprocessConfig = require("./svelte.config.js"); -const svelteNativePreprocessor = require("svelte-native-preprocessor"); +const preprocessConfig = require('./svelte.config.js'); +const svelteNativePreprocessor = require('svelte-native-preprocessor'); -module.exports = env => { - // Add your custom Activities, Services and other Android app components here. - const appComponents = env.appComponents || []; - appComponents.push(...[ - "@nativescript/core/ui/frame", - "@nativescript/core/ui/frame/activity", - ]); - - const platform = env && (env.android && "android" || env.ios && "ios" || env.platform); +module.exports = (env) => { + const platform = env && ((env.android && 'android') || (env.ios && 'ios') || env.platform); if (!platform) { - throw new Error("You need to provide a target platform!"); + throw new Error('You need to provide a target platform!'); } - const platforms = ["ios", "android"]; + const platforms = ['ios', 'android']; const projectRoot = __dirname; if (env.platform) { @@ -41,8 +34,8 @@ module.exports = env => { const { // The 'appPath' and 'appResourcesPath' values are fetched from // the nsconfig.json configuration file. - appPath = "src", - appResourcesPath = "App_Resources", + appPath = 'src', + appResourcesPath = 'App_Resources', // You can provide the following flags when running 'tns run android|ios' snapshot, // --env.snapshot @@ -55,9 +48,12 @@ module.exports = env => { unitTesting, // --env.unitTesting, testing, // --env.testing verbose, // --env.verbose + ci, // --env.ci snapshotInDocker, // --env.snapshotInDocker skipSnapshotTools, // --env.skipSnapshotTools - compileSnapshot // --env.compileSnapshot + compileSnapshot, // --env.compileSnapshot + appComponents = [], + entries = {}, } = env; const useLibs = compileSnapshot; @@ -70,14 +66,14 @@ module.exports = env => { appFullPath = resolve(projectRoot, 'app'); } const hasRootLevelScopedModules = nsWebpack.hasRootLevelScopedModules({ projectDir: projectRoot }); - let coreModulesPackageName = "tns-core-modules"; + let coreModulesPackageName = 'tns-core-modules'; const alias = env.alias || {}; alias['~/package.json'] = resolve(projectRoot, 'package.json'); alias['~'] = appFullPath; if (hasRootLevelScopedModules) { - coreModulesPackageName = "@nativescript/core"; - alias["tns-core-modules"] = coreModulesPackageName; + coreModulesPackageName = '@nativescript/core'; + alias['tns-core-modules'] = coreModulesPackageName; } const appResourcesFullPath = resolve(projectRoot, appResourcesPath); @@ -85,37 +81,39 @@ module.exports = env => { const entryModule = nsWebpack.getEntryModule(appFullPath, platform); const entryPath = `.${sep}${entryModule}.ts`; - const entries = env.entries || {}; - entries.bundle = entryPath; + Object.assign(entries, { bundle: entryPath }, entries); - const tsConfigPath = resolve(projectRoot, "tsconfig.json"); + const tsConfigPath = resolve(projectRoot, 'tsconfig.json'); - const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some(e => e.indexOf("@nativescript") > -1); - if (platform === "ios" && !areCoreModulesExternal && !testing) { - entries["tns_modules/@nativescript/core/inspector_modules"] = "inspector_modules"; - }; + const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some((e) => e.indexOf('@nativescript') > -1); + if (platform === 'ios' && !areCoreModulesExternal && !testing) { + entries['tns_modules/inspector_modules'] = '@nativescript/core/inspector_modules'; + } let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); const itemsToClean = [`${dist}/**/*`]; - if (platform === "android") { - itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); - itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); + if (platform === 'android') { + itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'src', 'main', 'assets', 'snapshots')}`); + itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'build', 'configurations', 'nativescript-android-snapshot')}`); } const noEmitOnErrorFromTSConfig = getNoEmitOnErrorFromTSConfig(tsConfigPath); + // Add your custom Activities, Services and other android app components here. + appComponents.push('@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity'); + nsWebpack.processAppComponents(appComponents, platform); const config = { - mode: production ? "production" : "development", + mode: production ? 'production' : 'development', context: appFullPath, externals, watchOptions: { ignored: [ appResourcesFullPath, // Don't watch hidden files - "**/.*", - ] + '**/.*', + ], }, target: nativescriptTarget, entry: entries, @@ -123,74 +121,78 @@ module.exports = env => { pathinfo: false, path: dist, sourceMapFilename, - libraryTarget: "commonjs2", - filename: "[name].js", - globalObject: "global", - hashSalt + libraryTarget: 'commonjs2', + filename: '[name].js', + globalObject: 'global', + hashSalt, }, resolve: { - extensions: [".ts", ".mjs", ".js", ".svelte", ".scss", ".css"], + extensions: ['.ts', '.mjs', '.js', '.svelte', '.scss', '.css'], // Resolve {N} system modules from @nativescript/core - modules: [ - resolve(__dirname, `node_modules/${coreModulesPackageName}`), - resolve(__dirname, "node_modules"), - `node_modules/${coreModulesPackageName}`, - "node_modules", - ], + modules: [resolve(__dirname, `node_modules/${coreModulesPackageName}`), resolve(__dirname, 'node_modules'), `node_modules/${coreModulesPackageName}`, 'node_modules'], alias, // resolve symlinks to symlinked modules - symlinks: true + symlinks: true, }, resolveLoader: { // don't resolve symlinks to symlinked loaders - symlinks: false + symlinks: false, }, node: { // Disable node shims that conflict with NativeScript - "http": false, - "timers": false, - "setImmediate": false, - "fs": "empty", - "__dirname": false, + http: false, + timers: false, + setImmediate: false, + fs: 'empty', + __dirname: false, }, - devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"), + devtool: hiddenSourceMap ? 'hidden-source-map' : sourceMap ? 'inline-source-map' : 'none', optimization: { - runtimeChunk: "single", + runtimeChunk: 'single', noEmitOnErrors: noEmitOnErrorFromTSConfig, splitChunks: { cacheGroups: { vendor: { - name: "vendor", - chunks: "all", + name: 'vendor', + chunks: 'all', test: (module, chunks) => { const moduleName = module.nameForCondition ? module.nameForCondition() : ''; - return /[\\/]node_modules[\\/]/.test(moduleName) || - appComponents.some(comp => comp === moduleName); - + return /[\\/]node_modules[\\/]/.test(moduleName) || appComponents.some((comp) => comp === moduleName); }, enforce: true, }, - } + }, }, minimize: !!uglify, minimizer: [ new TerserPlugin({ parallel: true, - cache: true, + cache: !ci, sourceMap: isAnySourceMapEnabled, terserOptions: { output: { comments: false, - semicolons: !isAnySourceMapEnabled + semicolons: !isAnySourceMapEnabled, }, compress: { // The Android SBG has problems parsing the output // when these options are enabled - 'collapse_vars': platform !== "android", - sequences: platform !== "android", - } - } - }) + collapse_vars: platform !== 'android', + sequences: platform !== 'android', + // For v8 Compatibility + keep_infinity: true, // for V8 + reduce_funcs: false, // for V8 + // custom + drop_console: production, + drop_debugger: true, + global_defs: { + __UGLIFIED__: true, + }, + }, + // Required for Element Level CSS, Observable Events, & Android Frame + keep_classnames: true, + }, + }), ], }, module: { @@ -199,42 +201,39 @@ module.exports = env => { include: join(appFullPath, entryPath), use: [ // Require all Android app components - platform === "android" && { - loader: "@nativescript/webpack/helpers/android-app-components-loader", - options: { modules: appComponents } + platform === 'android' && { + loader: '@nativescript/webpack/helpers/android-app-components-loader', + options: { modules: appComponents }, }, { - loader: "@nativescript/webpack/bundle-config-loader", + loader: '@nativescript/webpack/bundle-config-loader', options: { loadCss: !snapshot, // load the application css if in debug mode unitTesting, appFullPath, projectRoot, - ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) - } + ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform), + }, }, - ].filter(loader => !!loader) + ].filter((loader) => !!loader), }, { test: /\.(ts|css|scss|html|xml)$/, - use: "@nativescript/webpack/hmr/hot-loader" + use: '@nativescript/webpack/hmr/hot-loader', }, - { test: /\.(html|xml)$/, use: "@nativescript/webpack/helpers/xml-namespace-loader" }, + { test: /\.(html|xml)$/, use: '@nativescript/webpack/helpers/xml-namespace-loader' }, { test: /\.css$/, - use: "@nativescript/webpack/helpers/css2json-loader" + use: '@nativescript/webpack/helpers/css2json-loader', }, { test: /\.scss$/, - use: [ - "@nativescript/webpack/helpers/css2json-loader", - "sass-loader" - ] + use: ['@nativescript/webpack/helpers/css2json-loader', 'sass-loader'], }, { @@ -244,7 +243,7 @@ module.exports = env => { { test: /\.ts$/, use: { - loader: "ts-loader", + loader: 'ts-loader', options: { configFile: tsConfigPath, // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#faster-builds @@ -253,15 +252,13 @@ module.exports = env => { allowTsInNodeModules: true, compilerOptions: { sourceMap: isAnySourceMapEnabled, - declaration: false + declaration: false, }, getCustomTransformers: (program) => ({ - before: [ - require("@nativescript/webpack/transformers/ns-transform-native-classes").default - ] - }) + before: [require('@nativescript/webpack/transformers/ns-transform-native-classes').default], + }), }, - } + }, }, { test: /\.svelte$/, @@ -275,35 +272,30 @@ module.exports = env => { hotReload: env.production ? false : true, hotOptions: { injectCss: false, - native: true - } - } - } - ] - } - ] + native: true, + }, + }, + }, + ], + }, + ], }, plugins: [ // Define useful constants like TNS_WEBPACK new webpack.DefinePlugin({ - "global.TNS_WEBPACK": "true", - "global.isAndroid": platform === 'android', - "global.isIOS": platform === 'ios', - "process": "global.process", + 'global.TNS_WEBPACK': 'true', + 'global.isAndroid': platform === 'android', + 'global.isIOS': platform === 'ios', + process: 'global.process', }), // Remove all files from the out dir. new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: itemsToClean, - verbose: !!verbose + verbose: !!verbose, }), // Copy assets - new CopyWebpackPlugin([ - { from: { glob: 'assets/**', dot: false } }, - { from: { glob: 'fonts/**', dot: false } }, - { from: { glob: '**/*.jpg', dot: false } }, - { from: { glob: '**/*.png', dot: false } }, - ], copyIgnore), - new nsWebpack.GenerateNativeScriptEntryPointsPlugin("bundle"), + new CopyWebpackPlugin([{ from: { glob: 'assets/**', dot: false } }, { from: { glob: 'fonts/**', dot: false } }, { from: { glob: '**/*.jpg', dot: false } }, { from: { glob: '**/*.png', dot: false } }], copyIgnore), + new nsWebpack.GenerateNativeScriptEntryPointsPlugin('bundle'), // For instructions on how to set up workers with webpack // check out https://github.com/nativescript/worker-loader new NativeScriptWorkerPlugin(), @@ -322,36 +314,38 @@ module.exports = env => { memoryLimit: 4096, diagnosticOptions: { syntactic: true, - semantic: true - } - } - }) + semantic: true, + }, + }, + }), ], }; if (report) { // Generate report files for bundles content - config.plugins.push(new BundleAnalyzerPlugin({ - analyzerMode: "static", - openAnalyzer: false, - generateStatsFile: true, - reportFilename: resolve(projectRoot, "report", `report.html`), - statsFilename: resolve(projectRoot, "report", `stats.json`), - })); + config.plugins.push( + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false, + generateStatsFile: true, + reportFilename: resolve(projectRoot, 'report', `report.html`), + statsFilename: resolve(projectRoot, 'report', `stats.json`), + }) + ); } if (snapshot) { - config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "vendor", - requireModules: [ - "@nativescript/core/bundle-entry-points", - ], - projectRoot, - webpackConfig: config, - snapshotInDocker, - skipSnapshotTools, - useLibs - })); + config.plugins.push( + new nsWebpack.NativeScriptSnapshotPlugin({ + chunk: 'vendor', + requireModules: ['@nativescript/core/bundle-entry-points'], + projectRoot, + webpackConfig: config, + snapshotInDocker, + skipSnapshotTools, + useLibs, + }) + ); } if (hmr) { diff --git a/packages/webpack/templates/webpack.typescript.js b/packages/webpack/templates/webpack.typescript.js index cb43e5966..379ca48c2 100644 --- a/packages/webpack/templates/webpack.typescript.js +++ b/packages/webpack/templates/webpack.typescript.js @@ -1,338 +1,332 @@ -const { join, relative, resolve, sep } = require("path"); +const { join, relative, resolve, sep } = require('path'); const fs = require('fs'); -const webpack = require("webpack"); -const nsWebpack = require("@nativescript/webpack"); -const nativescriptTarget = require("@nativescript/webpack/nativescript-target"); -const { getNoEmitOnErrorFromTSConfig } = require("@nativescript/webpack/utils/tsconfig-utils"); -const { CleanWebpackPlugin } = require("clean-webpack-plugin"); -const CopyWebpackPlugin = require("copy-webpack-plugin"); +const webpack = require('webpack'); +const nsWebpack = require('@nativescript/webpack'); +const nativescriptTarget = require('@nativescript/webpack/nativescript-target'); +const { getNoEmitOnErrorFromTSConfig } = require('@nativescript/webpack/utils/tsconfig-utils'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); -const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); -const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); -const TerserPlugin = require("terser-webpack-plugin"); +const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); +const { NativeScriptWorkerPlugin } = require('nativescript-worker-loader/NativeScriptWorkerPlugin'); +const TerserPlugin = require('terser-webpack-plugin'); const hashSalt = Date.now().toString(); -module.exports = env => { - // Add your custom Activities, Services and other Android app components here. - const appComponents = env.appComponents || []; - appComponents.push(...[ - "@nativescript/core/ui/frame", - "@nativescript/core/ui/frame/activity", - ]); +module.exports = (env) => { + const platform = env && ((env.android && 'android') || (env.ios && 'ios') || env.platform); + if (!platform) { + throw new Error('You need to provide a target platform!'); + } - const platform = env && (env.android && "android" || env.ios && "ios" || env.platform); - if (!platform) { - throw new Error("You need to provide a target platform!"); - } + const platforms = ['ios', 'android']; + const projectRoot = __dirname; - const platforms = ["ios", "android"]; - const projectRoot = __dirname; + if (env.platform) { + platforms.push(env.platform); + } - if (env.platform) { - platforms.push(env.platform); - } + // Default destination inside platforms//... + const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot)); - // Default destination inside platforms//... - const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot)); + const { + // The 'appPath' and 'appResourcesPath' values are fetched from + // the nsconfig.json configuration file. + appPath = 'src', + appResourcesPath = 'App_Resources', - const { - // The 'appPath' and 'appResourcesPath' values are fetched from - // the nsconfig.json configuration file. - appPath = "src", - appResourcesPath = "App_Resources", + // You can provide the following flags when running 'tns run android|ios' + snapshot, // --env.snapshot + production, // --env.production + uglify, // --env.uglify + report, // --env.report + sourceMap, // --env.sourceMap + hiddenSourceMap, // --env.hiddenSourceMap + hmr, // --env.hmr, + unitTesting, // --env.unitTesting, + testing, // --env.testing + verbose, // --env.verbose + ci, // --env.ci + snapshotInDocker, // --env.snapshotInDocker + skipSnapshotTools, // --env.skipSnapshotTools + compileSnapshot, // --env.compileSnapshot + appComponents = [], + entries = {}, + } = env; - // You can provide the following flags when running 'tns run android|ios' - snapshot, // --env.snapshot - production, // --env.production - uglify, // --env.uglify - report, // --env.report - sourceMap, // --env.sourceMap - hiddenSourceMap, // --env.hiddenSourceMap - hmr, // --env.hmr, - unitTesting, // --env.unitTesting, - testing, // --env.testing - verbose, // --env.verbose - snapshotInDocker, // --env.snapshotInDocker - skipSnapshotTools, // --env.skipSnapshotTools - compileSnapshot // --env.compileSnapshot - } = env; + const useLibs = compileSnapshot; + const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; + const externals = nsWebpack.getConvertedExternals(env.externals); - const useLibs = compileSnapshot; - const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; - const externals = nsWebpack.getConvertedExternals(env.externals); + let appFullPath = resolve(projectRoot, appPath); + if (!fs.existsSync(appFullPath)) { + // some apps use 'app' directory + appFullPath = resolve(projectRoot, 'app'); + } + const hasRootLevelScopedModules = nsWebpack.hasRootLevelScopedModules({ projectDir: projectRoot }); + let coreModulesPackageName = 'tns-core-modules'; + const alias = env.alias || {}; + alias['~/package.json'] = resolve(projectRoot, 'package.json'); + alias['~'] = appFullPath; - let appFullPath = resolve(projectRoot, appPath); - if (!fs.existsSync(appFullPath)) { - // some apps use 'app' directory - appFullPath = resolve(projectRoot, 'app'); - } - const hasRootLevelScopedModules = nsWebpack.hasRootLevelScopedModules({ projectDir: projectRoot }); - let coreModulesPackageName = "tns-core-modules"; - const alias = env.alias || {}; - alias['~/package.json'] = resolve(projectRoot, 'package.json'); - alias['~'] = appFullPath; + if (hasRootLevelScopedModules) { + coreModulesPackageName = '@nativescript/core'; + alias['tns-core-modules'] = coreModulesPackageName; + } + const appResourcesFullPath = resolve(projectRoot, appResourcesPath); - if (hasRootLevelScopedModules) { - coreModulesPackageName = "@nativescript/core"; - alias["tns-core-modules"] = coreModulesPackageName; - } - const appResourcesFullPath = resolve(projectRoot, appResourcesPath); + const copyIgnore = { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }; - const copyIgnore = { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }; + const entryModule = nsWebpack.getEntryModule(appFullPath, platform); + const entryPath = `.${sep}${entryModule}.ts`; + Object.assign(entries, { bundle: entryPath }, entries); - const entryModule = nsWebpack.getEntryModule(appFullPath, platform); - const entryPath = `.${sep}${entryModule}.ts`; - const entries = env.entries || {}; - entries.bundle = entryPath; + const tsConfigPath = resolve(projectRoot, 'tsconfig.json'); - const tsConfigPath = resolve(projectRoot, "tsconfig.json"); + const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some((e) => e.indexOf('@nativescript') > -1); + if (platform === 'ios' && !areCoreModulesExternal && !testing) { + entries['tns_modules/inspector_modules'] = '@nativescript/core/inspector_modules'; + } - const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some(e => e.indexOf("@nativescript") > -1); - if (platform === "ios" && !areCoreModulesExternal && !testing) { - entries["tns_modules/@nativescript/core/inspector_modules"] = "inspector_modules"; - }; + let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); - let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const itemsToClean = [`${dist}/**/*`]; + if (platform === 'android') { + itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'src', 'main', 'assets', 'snapshots')}`); + itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'build', 'configurations', 'nativescript-android-snapshot')}`); + } - const itemsToClean = [`${dist}/**/*`]; - if (platform === "android") { - itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); - itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); - } + const noEmitOnErrorFromTSConfig = getNoEmitOnErrorFromTSConfig(tsConfigPath); - const noEmitOnErrorFromTSConfig = getNoEmitOnErrorFromTSConfig(tsConfigPath); + // Add your custom Activities, Services and other android app components here. + appComponents.push('@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity'); - nsWebpack.processAppComponents(appComponents, platform); - const config = { - mode: production ? "production" : "development", - context: appFullPath, - externals, - watchOptions: { - ignored: [ - appResourcesFullPath, - // Don't watch hidden files - "**/.*", - ] - }, - target: nativescriptTarget, - entry: entries, - output: { - pathinfo: false, - path: dist, - sourceMapFilename, - libraryTarget: "commonjs2", - filename: "[name].js", - globalObject: "global", - hashSalt - }, - resolve: { - extensions: [".ts", ".js", ".scss", ".css"], - // Resolve {N} system modules from @nativescript/core - modules: [ - resolve(__dirname, `node_modules/${coreModulesPackageName}`), - resolve(__dirname, "node_modules"), - `node_modules/${coreModulesPackageName}`, - "node_modules", - ], - alias, - // resolve symlinks to symlinked modules - symlinks: true - }, - resolveLoader: { - // don't resolve symlinks to symlinked loaders - symlinks: false - }, - node: { - // Disable node shims that conflict with NativeScript - "http": false, - "timers": false, - "setImmediate": false, - "fs": "empty", - "__dirname": false, - }, - devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"), - optimization: { - runtimeChunk: "single", - noEmitOnErrors: noEmitOnErrorFromTSConfig, - splitChunks: { - cacheGroups: { - vendor: { - name: "vendor", - chunks: "all", - test: (module, chunks) => { - const moduleName = module.nameForCondition ? module.nameForCondition() : ''; - return /[\\/]node_modules[\\/]/.test(moduleName) || - appComponents.some(comp => comp === moduleName); + nsWebpack.processAppComponents(appComponents, platform); + const config = { + mode: production ? 'production' : 'development', + context: appFullPath, + externals, + watchOptions: { + ignored: [ + appResourcesFullPath, + // Don't watch hidden files + '**/.*', + ], + }, + target: nativescriptTarget, + entry: entries, + output: { + pathinfo: false, + path: dist, + sourceMapFilename, + libraryTarget: 'commonjs2', + filename: '[name].js', + globalObject: 'global', + hashSalt, + }, + resolve: { + extensions: ['.ts', '.js', '.scss', '.css'], + // Resolve {N} system modules from @nativescript/core + modules: [resolve(__dirname, `node_modules/${coreModulesPackageName}`), resolve(__dirname, 'node_modules'), `node_modules/${coreModulesPackageName}`, 'node_modules'], + alias, + // resolve symlinks to symlinked modules + symlinks: true, + }, + resolveLoader: { + // don't resolve symlinks to symlinked loaders + symlinks: false, + }, + node: { + // Disable node shims that conflict with NativeScript + http: false, + timers: false, + setImmediate: false, + fs: 'empty', + __dirname: false, + }, + devtool: hiddenSourceMap ? 'hidden-source-map' : sourceMap ? 'inline-source-map' : 'none', + optimization: { + runtimeChunk: 'single', + noEmitOnErrors: noEmitOnErrorFromTSConfig, + splitChunks: { + cacheGroups: { + vendor: { + name: 'vendor', + chunks: 'all', + test: (module, chunks) => { + const moduleName = module.nameForCondition ? module.nameForCondition() : ''; + return /[\\/]node_modules[\\/]/.test(moduleName) || appComponents.some((comp) => comp === moduleName); + }, + enforce: true, + }, + }, + }, + minimize: !!uglify, + minimizer: [ + new TerserPlugin({ + parallel: true, + cache: !ci, + sourceMap: isAnySourceMapEnabled, + terserOptions: { + output: { + comments: false, + semicolons: !isAnySourceMapEnabled, + }, + compress: { + // The Android SBG has problems parsing the output + // when these options are enabled + collapse_vars: platform !== 'android', + sequences: platform !== 'android', + // For v8 Compatibility + keep_infinity: true, // for V8 + reduce_funcs: false, // for V8 + // custom + drop_console: production, + drop_debugger: true, + global_defs: { + __UGLIFIED__: true, + }, + }, + // Required for Element Level CSS, Observable Events, & Android Frame + keep_classnames: true, + }, + }), + ], + }, + module: { + rules: [ + { + include: join(appFullPath, entryPath), + use: [ + // Require all Android app components + platform === 'android' && { + loader: '@nativescript/webpack/helpers/android-app-components-loader', + options: { modules: appComponents }, + }, - }, - enforce: true, - }, - } - }, - minimize: !!uglify, - minimizer: [ - new TerserPlugin({ - parallel: true, - cache: true, - sourceMap: isAnySourceMapEnabled, - terserOptions: { - output: { - comments: false, - semicolons: !isAnySourceMapEnabled - }, - compress: { - // The Android SBG has problems parsing the output - // when these options are enabled - 'collapse_vars': platform !== "android", - sequences: platform !== "android", - } - } - }) - ], - }, - module: { - rules: [ - { - include: join(appFullPath, entryPath), - use: [ - // Require all Android app components - platform === "android" && { - loader: "@nativescript/webpack/helpers/android-app-components-loader", - options: { modules: appComponents } - }, + { + loader: '@nativescript/webpack/bundle-config-loader', + options: { + loadCss: !snapshot, // load the application css if in debug mode + unitTesting, + appFullPath, + projectRoot, + ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform), + }, + }, + ].filter((loader) => !!loader), + }, - { - loader: "@nativescript/webpack/bundle-config-loader", - options: { - loadCss: !snapshot, // load the application css if in debug mode - unitTesting, - appFullPath, - projectRoot, - ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) - } - }, - ].filter(loader => !!loader) - }, + { + test: /\.(ts|css|scss|html|xml)$/, + use: '@nativescript/webpack/hmr/hot-loader', + }, - { - test: /\.(ts|css|scss|html|xml)$/, - use: "@nativescript/webpack/hmr/hot-loader" - }, + { test: /\.(html|xml)$/, use: '@nativescript/webpack/helpers/xml-namespace-loader' }, - { test: /\.(html|xml)$/, use: "@nativescript/webpack/helpers/xml-namespace-loader" }, + { + test: /\.css$/, + use: '@nativescript/webpack/helpers/css2json-loader', + }, - { - test: /\.css$/, - use: "@nativescript/webpack/helpers/css2json-loader" - }, + { + test: /\.scss$/, + use: ['@nativescript/webpack/helpers/css2json-loader', 'sass-loader'], + }, - { - test: /\.scss$/, - use: [ - "@nativescript/webpack/helpers/css2json-loader", - "sass-loader" - ] - }, + { + test: /\.ts$/, + use: { + loader: 'ts-loader', + options: { + configFile: tsConfigPath, + // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#faster-builds + // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#hot-module-replacement + transpileOnly: true, + allowTsInNodeModules: true, + compilerOptions: { + sourceMap: isAnySourceMapEnabled, + declaration: false, + }, + getCustomTransformers: (program) => ({ + before: [require('@nativescript/webpack/transformers/ns-transform-native-classes').default], + }), + }, + }, + }, + ], + }, + plugins: [ + // Define useful constants like TNS_WEBPACK + new webpack.DefinePlugin({ + 'global.TNS_WEBPACK': 'true', + 'global.isAndroid': platform === 'android', + 'global.isIOS': platform === 'ios', + process: 'global.process', + }), + // Remove all files from the out dir. + new CleanWebpackPlugin({ + cleanOnceBeforeBuildPatterns: itemsToClean, + verbose: !!verbose, + }), + // Copy assets + new CopyWebpackPlugin([{ from: { glob: 'assets/**', dot: false } }, { from: { glob: 'fonts/**', dot: false } }, { from: { glob: '**/*.jpg', dot: false } }, { from: { glob: '**/*.png', dot: false } }], copyIgnore), + new nsWebpack.GenerateNativeScriptEntryPointsPlugin('bundle'), + // For instructions on how to set up workers with webpack + // check out https://github.com/nativescript/worker-loader + new NativeScriptWorkerPlugin(), + new nsWebpack.PlatformFSPlugin({ + platform, + platforms, + }), + // Does IPC communication with the {N} CLI to notify events when running in watch mode. + new nsWebpack.WatchStateLoggerPlugin(), + // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#faster-builds + // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#hot-module-replacement + new ForkTsCheckerWebpackPlugin({ + async: false, + typescript: { + configFile: tsConfigPath, + memoryLimit: 4096, + diagnosticOptions: { + syntactic: true, + semantic: true, + }, + }, + }), + ], + }; - { - test: /\.ts$/, - use: { - loader: "ts-loader", - options: { - configFile: tsConfigPath, - // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#faster-builds - // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#hot-module-replacement - transpileOnly: true, - allowTsInNodeModules: true, - compilerOptions: { - sourceMap: isAnySourceMapEnabled, - declaration: false - }, - getCustomTransformers: (program) => ({ - before: [ - require("@nativescript/webpack/transformers/ns-transform-native-classes").default - ] - }) - }, - } - }, - ] - }, - plugins: [ - // Define useful constants like TNS_WEBPACK - new webpack.DefinePlugin({ - "global.TNS_WEBPACK": "true", - "global.isAndroid": platform === 'android', - "global.isIOS": platform === 'ios', - "process": "global.process", - }), - // Remove all files from the out dir. - new CleanWebpackPlugin({ - cleanOnceBeforeBuildPatterns: itemsToClean, - verbose: !!verbose - }), - // Copy assets - new CopyWebpackPlugin([ - { from: { glob: 'assets/**', dot: false } }, - { from: { glob: 'fonts/**', dot: false } }, - { from: { glob: '**/*.jpg', dot: false } }, - { from: { glob: '**/*.png', dot: false } }, - ], copyIgnore), - new nsWebpack.GenerateNativeScriptEntryPointsPlugin("bundle"), - // For instructions on how to set up workers with webpack - // check out https://github.com/nativescript/worker-loader - new NativeScriptWorkerPlugin(), - new nsWebpack.PlatformFSPlugin({ - platform, - platforms, - }), - // Does IPC communication with the {N} CLI to notify events when running in watch mode. - new nsWebpack.WatchStateLoggerPlugin(), - // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#faster-builds - // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#hot-module-replacement - new ForkTsCheckerWebpackPlugin({ - async: false, - typescript: { - configFile: tsConfigPath, - memoryLimit: 4096, - diagnosticOptions: { - syntactic: true, - semantic: true - } - } - }) - ], - }; + if (report) { + // Generate report files for bundles content + config.plugins.push( + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false, + generateStatsFile: true, + reportFilename: resolve(projectRoot, 'report', `report.html`), + statsFilename: resolve(projectRoot, 'report', `stats.json`), + }) + ); + } - if (report) { - // Generate report files for bundles content - config.plugins.push(new BundleAnalyzerPlugin({ - analyzerMode: "static", - openAnalyzer: false, - generateStatsFile: true, - reportFilename: resolve(projectRoot, "report", `report.html`), - statsFilename: resolve(projectRoot, "report", `stats.json`), - })); - } + if (snapshot) { + config.plugins.push( + new nsWebpack.NativeScriptSnapshotPlugin({ + chunk: 'vendor', + requireModules: ['@nativescript/core/bundle-entry-points'], + projectRoot, + webpackConfig: config, + snapshotInDocker, + skipSnapshotTools, + useLibs, + }) + ); + } - if (snapshot) { - config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "vendor", - requireModules: [ - "@nativescript/core/bundle-entry-points", - ], - projectRoot, - webpackConfig: config, - snapshotInDocker, - skipSnapshotTools, - useLibs - })); - } + if (hmr) { + config.plugins.push(new webpack.HotModuleReplacementPlugin()); + } - if (hmr) { - config.plugins.push(new webpack.HotModuleReplacementPlugin()); - } - - return config; + return config; }; diff --git a/packages/webpack/templates/webpack.vue.js b/packages/webpack/templates/webpack.vue.js index 12987e9bc..cfcf64a73 100644 --- a/packages/webpack/templates/webpack.vue.js +++ b/packages/webpack/templates/webpack.vue.js @@ -1,368 +1,357 @@ -const { join, relative, resolve, sep } = require("path"); +const { join, relative, resolve, sep } = require('path'); -const webpack = require("webpack"); -const { CleanWebpackPlugin } = require("clean-webpack-plugin"); -const CopyWebpackPlugin = require("copy-webpack-plugin"); -const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); -const TerserPlugin = require("terser-webpack-plugin"); +const webpack = require('webpack'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); +const TerserPlugin = require('terser-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); -const NsVueTemplateCompiler = require("nativescript-vue-template-compiler"); +const NsVueTemplateCompiler = require('nativescript-vue-template-compiler'); -const nsWebpack = require("@nativescript/webpack"); -const nativescriptTarget = require("@nativescript/webpack/nativescript-target"); -const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); +const nsWebpack = require('@nativescript/webpack'); +const nativescriptTarget = require('@nativescript/webpack/nativescript-target'); +const { NativeScriptWorkerPlugin } = require('nativescript-worker-loader/NativeScriptWorkerPlugin'); const hashSalt = Date.now().toString(); -module.exports = env => { - // Add your custom Activities, Services and other android app components here. - const appComponents = env.appComponents || []; - appComponents.push(...[ - "@nativescript/core/ui/frame", - "@nativescript/core/ui/frame/activity", - ]); +module.exports = (env) => { + const platform = env && ((env.android && 'android') || (env.ios && 'ios') || env.platform); + if (!platform) { + throw new Error('You need to provide a target platform!'); + } - const platform = env && (env.android && "android" || env.ios && "ios" || env.platform); - if (!platform) { - throw new Error("You need to provide a target platform!"); - } + const platforms = ['ios', 'android']; + const projectRoot = __dirname; - const platforms = ["ios", "android"]; - const projectRoot = __dirname; + if (env.platform) { + platforms.push(env.platform); + } - if (env.platform) { - platforms.push(env.platform); - } + // Default destination inside platforms//... + const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot)); - // Default destination inside platforms//... - const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot)); + const { + // The 'appPath' and 'appResourcesPath' values are fetched from + // the nsconfig.json configuration file. + appPath = 'app', + appResourcesPath = 'app/App_Resources', - const { - // The 'appPath' and 'appResourcesPath' values are fetched from - // the nsconfig.json configuration file. - appPath = "app", - appResourcesPath = "app/App_Resources", + // You can provide the following flags when running 'tns run android|ios' + snapshot, // --env.snapshot + production, // --env.production + report, // --env.report + hmr, // --env.hmr + sourceMap, // --env.sourceMap + hiddenSourceMap, // --env.hiddenSourceMap + unitTesting, // --env.unitTesting + testing, // --env.testing + verbose, // --env.verbose + ci, // --env.ci + snapshotInDocker, // --env.snapshotInDocker + skipSnapshotTools, // --env.skipSnapshotTools + compileSnapshot, // --env.compileSnapshot + appComponents = [], + entries = {}, + } = env; - // You can provide the following flags when running 'tns run android|ios' - snapshot, // --env.snapshot - production, // --env.production - report, // --env.report - hmr, // --env.hmr - sourceMap, // --env.sourceMap - hiddenSourceMap, // --env.hiddenSourceMap - unitTesting, // --env.unitTesting - testing, // --env.testing - verbose, // --env.verbose - snapshotInDocker, // --env.snapshotInDocker - skipSnapshotTools, // --env.skipSnapshotTools - compileSnapshot // --env.compileSnapshot - } = env; + const useLibs = compileSnapshot; + const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; + const externals = nsWebpack.getConvertedExternals(env.externals); - const useLibs = compileSnapshot; - const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; - const externals = nsWebpack.getConvertedExternals(env.externals); + const mode = production ? 'production' : 'development'; - const mode = production ? "production" : "development" + const appFullPath = resolve(projectRoot, appPath); + const hasRootLevelScopedModules = nsWebpack.hasRootLevelScopedModules({ projectDir: projectRoot }); + let coreModulesPackageName = 'tns-core-modules'; + const alias = env.alias || {}; + alias['~/package.json'] = resolve(projectRoot, 'package.json'); + alias['~'] = appFullPath; + alias['@'] = appFullPath; + alias['vue'] = 'nativescript-vue'; - const appFullPath = resolve(projectRoot, appPath); - const hasRootLevelScopedModules = nsWebpack.hasRootLevelScopedModules({ projectDir: projectRoot }); - let coreModulesPackageName = "tns-core-modules"; - const alias = env.alias || {}; - alias['~/package.json'] = resolve(projectRoot, 'package.json'); - alias['~'] = appFullPath; - alias['@'] = appFullPath; - alias['vue'] = 'nativescript-vue'; + if (hasRootLevelScopedModules) { + coreModulesPackageName = '@nativescript/core'; + alias['tns-core-modules'] = coreModulesPackageName; + } - if (hasRootLevelScopedModules) { - coreModulesPackageName = "@nativescript/core"; - alias["tns-core-modules"] = coreModulesPackageName; - } + const appResourcesFullPath = resolve(projectRoot, appResourcesPath); - const appResourcesFullPath = resolve(projectRoot, appResourcesPath); + const copyIgnore = { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }; - const copyIgnore = { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }; + const entryModule = nsWebpack.getEntryModule(appFullPath, platform); + const entryPath = `.${sep}${entryModule}`; + Object.assign(entries, { bundle: entryPath }, entries); - const entryModule = nsWebpack.getEntryModule(appFullPath, platform); - const entryPath = `.${sep}${entryModule}`; - const entries = env.entries || {}; - entries.bundle = entryPath; + const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some((e) => e.indexOf('@nativescript') > -1); + if (platform === 'ios' && !areCoreModulesExternal && !testing) { + entries['tns_modules/inspector_modules'] = '@nativescript/core/inspector_modules'; + } + console.log(`Bundling application for entryPath ${entryPath}...`); - const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some(e => e.indexOf("@nativescript") > -1); - if (platform === "ios" && !areCoreModulesExternal && !testing) { - entries["tns_modules/@nativescript/core/inspector_modules"] = "inspector_modules"; - }; - console.log(`Bundling application for entryPath ${entryPath}...`); + let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); - let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const itemsToClean = [`${dist}/**/*`]; + if (platform === 'android') { + itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'src', 'main', 'assets', 'snapshots')}`); + itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'build', 'configurations', 'nativescript-android-snapshot')}`); + } - const itemsToClean = [`${dist}/**/*`]; - if (platform === "android") { - itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); - itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); - } + // Add your custom Activities, Services and other android app components here. + appComponents.push('@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity'); - nsWebpack.processAppComponents(appComponents, platform); - const config = { - mode: mode, - context: appFullPath, - externals, - watchOptions: { - ignored: [ - appResourcesFullPath, - // Don't watch hidden files - "**/.*", - ], - }, - target: nativescriptTarget, - // target: nativeScriptVueTarget, - entry: entries, - output: { - pathinfo: false, - path: dist, - sourceMapFilename, - libraryTarget: "commonjs2", - filename: "[name].js", - globalObject: "global", - hashSalt - }, - resolve: { - extensions: [".vue", ".ts", ".js", ".scss", ".css"], - // Resolve {N} system modules from @nativescript/core - modules: [ - resolve(__dirname, `node_modules/${coreModulesPackageName}`), - resolve(__dirname, "node_modules"), - `node_modules/${coreModulesPackageName}`, - "node_modules", - ], - alias, - // resolve symlinks to symlinked modules - symlinks: true, - }, - resolveLoader: { - // don't resolve symlinks to symlinked loaders - symlinks: false, - }, - node: { - // Disable node shims that conflict with NativeScript - "http": false, - "timers": false, - "setImmediate": false, - "fs": "empty", - "__dirname": false, - }, - devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"), - optimization: { - runtimeChunk: "single", - noEmitOnErrors: true, - splitChunks: { - cacheGroups: { - vendor: { - name: "vendor", - chunks: "all", - test: (module) => { - const moduleName = module.nameForCondition ? module.nameForCondition() : ''; - return /[\\/]node_modules[\\/]/.test(moduleName) || - appComponents.some(comp => comp === moduleName); + nsWebpack.processAppComponents(appComponents, platform); + const config = { + mode: mode, + context: appFullPath, + externals, + watchOptions: { + ignored: [ + appResourcesFullPath, + // Don't watch hidden files + '**/.*', + ], + }, + target: nativescriptTarget, + // target: nativeScriptVueTarget, + entry: entries, + output: { + pathinfo: false, + path: dist, + sourceMapFilename, + libraryTarget: 'commonjs2', + filename: '[name].js', + globalObject: 'global', + hashSalt, + }, + resolve: { + extensions: ['.vue', '.ts', '.js', '.scss', '.css'], + // Resolve {N} system modules from @nativescript/core + modules: [resolve(__dirname, `node_modules/${coreModulesPackageName}`), resolve(__dirname, 'node_modules'), `node_modules/${coreModulesPackageName}`, 'node_modules'], + alias, + // resolve symlinks to symlinked modules + symlinks: true, + }, + resolveLoader: { + // don't resolve symlinks to symlinked loaders + symlinks: false, + }, + node: { + // Disable node shims that conflict with NativeScript + http: false, + timers: false, + setImmediate: false, + fs: 'empty', + __dirname: false, + }, + devtool: hiddenSourceMap ? 'hidden-source-map' : sourceMap ? 'inline-source-map' : 'none', + optimization: { + runtimeChunk: 'single', + noEmitOnErrors: true, + splitChunks: { + cacheGroups: { + vendor: { + name: 'vendor', + chunks: 'all', + test: (module) => { + const moduleName = module.nameForCondition ? module.nameForCondition() : ''; + return /[\\/]node_modules[\\/]/.test(moduleName) || appComponents.some((comp) => comp === moduleName); + }, + enforce: true, + }, + }, + }, + minimize: Boolean(production), + minimizer: [ + new TerserPlugin({ + parallel: true, + cache: !ci, + sourceMap: isAnySourceMapEnabled, + terserOptions: { + output: { + comments: false, + semicolons: !isAnySourceMapEnabled, + }, + compress: { + // The Android SBG has problems parsing the output + // when these options are enabled + collapse_vars: platform !== 'android', + sequences: platform !== 'android', + // For v8 Compatibility + keep_infinity: true, // for V8 + reduce_funcs: false, // for V8 + // custom + drop_console: production, + drop_debugger: true, + global_defs: { + __UGLIFIED__: true, + }, + }, + keep_fnames: true, + // Required for Element Level CSS, Observable Events, & Android Frame + keep_classnames: true, + }, + }), + ], + }, + module: { + rules: [ + { + include: [join(appFullPath, entryPath + '.js'), join(appFullPath, entryPath + '.ts')], + use: [ + // Require all Android app components + platform === 'android' && { + loader: '@nativescript/webpack/helpers/android-app-components-loader', + options: { modules: appComponents }, + }, - }, - enforce: true, - }, - }, - }, - minimize: Boolean(production), - minimizer: [ - new TerserPlugin({ - parallel: true, - cache: true, - sourceMap: isAnySourceMapEnabled, - terserOptions: { - output: { - comments: false, - semicolons: !isAnySourceMapEnabled - }, - compress: { - // The Android SBG has problems parsing the output - // when these options are enabled - 'collapse_vars': platform !== "android", - sequences: platform !== "android", - }, - keep_fnames: true, - }, - }), - ], - }, - module: { - rules: [{ - include: [join(appFullPath, entryPath + ".js"), join(appFullPath, entryPath + ".ts")], - use: [ - // Require all Android app components - platform === "android" && { - loader: "@nativescript/webpack/helpers/android-app-components-loader", - options: { modules: appComponents }, - }, + { + loader: '@nativescript/webpack/bundle-config-loader', + options: { + registerPages: true, // applicable only for non-angular apps + loadCss: !snapshot, // load the application css if in debug mode + unitTesting, + appFullPath, + projectRoot, + ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform), + }, + }, + ].filter((loader) => Boolean(loader)), + }, + { + test: /[\/|\\]app\.css$/, + use: [ + '@nativescript/webpack/helpers/style-hot-loader', + { + loader: '@nativescript/webpack/helpers/css2json-loader', + options: { useForImports: true }, + }, + ], + }, + { + test: /[\/|\\]app\.scss$/, + use: [ + '@nativescript/webpack/helpers/style-hot-loader', + { + loader: '@nativescript/webpack/helpers/css2json-loader', + options: { useForImports: true }, + }, + 'sass-loader', + ], + }, + { + test: /\.css$/, + exclude: /[\/|\\]app\.css$/, + use: ['@nativescript/webpack/helpers/style-hot-loader', '@nativescript/webpack/helpers/apply-css-loader.js', { loader: 'css-loader', options: { url: false } }], + }, + { + test: /\.scss$/, + exclude: /[\/|\\]app\.scss$/, + use: ['@nativescript/webpack/helpers/style-hot-loader', '@nativescript/webpack/helpers/apply-css-loader.js', { loader: 'css-loader', options: { url: false } }, 'sass-loader'], + }, + { + test: /\.js$/, + loader: 'babel-loader', + }, + { + test: /\.ts$/, + loader: 'ts-loader', + options: { + appendTsSuffixTo: [/\.vue$/], + allowTsInNodeModules: true, + compilerOptions: { + declaration: false, + }, + getCustomTransformers: (program) => ({ + before: [require('@nativescript/webpack/transformers/ns-transform-native-classes').default], + }), + }, + }, + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + compiler: NsVueTemplateCompiler, + }, + }, + ], + }, + plugins: [ + // ... Vue Loader plugin omitted + // make sure to include the plugin! + new VueLoaderPlugin(), + // Define useful constants like TNS_WEBPACK + new webpack.DefinePlugin({ + 'global.TNS_WEBPACK': 'true', + 'global.isAndroid': platform === 'android', + 'global.isIOS': platform === 'ios', + TNS_ENV: JSON.stringify(mode), + process: 'global.process', + }), + // Remove all files from the out dir. + new CleanWebpackPlugin({ + cleanOnceBeforeBuildPatterns: itemsToClean, + verbose: !!verbose, + }), + // Copy assets + new CopyWebpackPlugin([{ from: { glob: 'assets/**', dot: false } }, { from: { glob: 'fonts/**', dot: false } }, { from: { glob: '**/*.jpg', dot: false } }, { from: { glob: '**/*.png', dot: false } }], copyIgnore), + new nsWebpack.GenerateNativeScriptEntryPointsPlugin('bundle'), + // For instructions on how to set up workers with webpack + // check out https://github.com/nativescript/worker-loader + new NativeScriptWorkerPlugin(), + new nsWebpack.PlatformFSPlugin({ + platform, + platforms, + }), + // Does IPC communication with the {N} CLI to notify events when running in watch mode. + new nsWebpack.WatchStateLoggerPlugin(), + ], + }; - { - loader: "@nativescript/webpack/bundle-config-loader", - options: { - registerPages: true, // applicable only for non-angular apps - loadCss: !snapshot, // load the application css if in debug mode - unitTesting, - appFullPath, - projectRoot, - ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) - }, - }, - ].filter(loader => Boolean(loader)), - }, - { - test: /[\/|\\]app\.css$/, - use: [ - '@nativescript/webpack/helpers/style-hot-loader', - { - loader: "@nativescript/webpack/helpers/css2json-loader", - options: { useForImports: true } - }, - ], - }, - { - test: /[\/|\\]app\.scss$/, - use: [ - '@nativescript/webpack/helpers/style-hot-loader', - { - loader: "@nativescript/webpack/helpers/css2json-loader", - options: { useForImports: true } - }, - 'sass-loader', - ], - }, - { - test: /\.css$/, - exclude: /[\/|\\]app\.css$/, - use: [ - '@nativescript/webpack/helpers/style-hot-loader', - '@nativescript/webpack/helpers/apply-css-loader.js', - { loader: "css-loader", options: { url: false } }, - ], - }, - { - test: /\.scss$/, - exclude: /[\/|\\]app\.scss$/, - use: [ - '@nativescript/webpack/helpers/style-hot-loader', - '@nativescript/webpack/helpers/apply-css-loader.js', - { loader: "css-loader", options: { url: false } }, - 'sass-loader', - ], - }, - { - test: /\.js$/, - loader: 'babel-loader', - }, - { - test: /\.ts$/, - loader: 'ts-loader', - options: { - appendTsSuffixTo: [/\.vue$/], - allowTsInNodeModules: true, - compilerOptions: { - declaration: false - }, - getCustomTransformers: (program) => ({ - before: [ - require("@nativescript/webpack/transformers/ns-transform-native-classes").default - ] - }) - }, - }, - { - test: /\.vue$/, - loader: "vue-loader", - options: { - compiler: NsVueTemplateCompiler, - }, - }, - ], - }, - plugins: [ - // ... Vue Loader plugin omitted - // make sure to include the plugin! - new VueLoaderPlugin(), - // Define useful constants like TNS_WEBPACK - new webpack.DefinePlugin({ - "global.TNS_WEBPACK": "true", - "global.isAndroid": platform === 'android', - "global.isIOS": platform === 'ios', - "TNS_ENV": JSON.stringify(mode), - "process": "global.process" - }), - // Remove all files from the out dir. - new CleanWebpackPlugin({ - cleanOnceBeforeBuildPatterns: itemsToClean, - verbose: !!verbose - }), - // Copy assets - new CopyWebpackPlugin([ - { from: { glob: 'assets/**', dot: false } }, - { from: { glob: 'fonts/**', dot: false } }, - { from: { glob: '**/*.jpg', dot: false } }, - { from: { glob: '**/*.png', dot: false } }, - ], copyIgnore), - new nsWebpack.GenerateNativeScriptEntryPointsPlugin("bundle"), - // For instructions on how to set up workers with webpack - // check out https://github.com/nativescript/worker-loader - new NativeScriptWorkerPlugin(), - new nsWebpack.PlatformFSPlugin({ - platform, - platforms, - }), - // Does IPC communication with the {N} CLI to notify events when running in watch mode. - new nsWebpack.WatchStateLoggerPlugin() - ], - }; + if (unitTesting) { + config.module.rules.push( + { + test: /-page\.js$/, + use: '@nativescript/webpack/helpers/script-hot-loader', + }, + { + test: /\.(html|xml)$/, + use: '@nativescript/webpack/helpers/markup-hot-loader', + }, - if (unitTesting) { - config.module.rules.push( - { - test: /-page\.js$/, - use: "@nativescript/webpack/helpers/script-hot-loader" - }, - { - test: /\.(html|xml)$/, - use: "@nativescript/webpack/helpers/markup-hot-loader" - }, + { test: /\.(html|xml)$/, use: '@nativescript/webpack/helpers/xml-namespace-loader' } + ); + } - { test: /\.(html|xml)$/, use: "@nativescript/webpack/helpers/xml-namespace-loader" } - ); - } + if (report) { + // Generate report files for bundles content + config.plugins.push( + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false, + generateStatsFile: true, + reportFilename: resolve(projectRoot, 'report', `report.html`), + statsFilename: resolve(projectRoot, 'report', `stats.json`), + }) + ); + } - if (report) { - // Generate report files for bundles content - config.plugins.push(new BundleAnalyzerPlugin({ - analyzerMode: "static", - openAnalyzer: false, - generateStatsFile: true, - reportFilename: resolve(projectRoot, "report", `report.html`), - statsFilename: resolve(projectRoot, "report", `stats.json`), - })); - } + if (snapshot) { + config.plugins.push( + new nsWebpack.NativeScriptSnapshotPlugin({ + chunk: 'vendor', + requireModules: ['@nativescript/core/bundle-entry-points'], + projectRoot, + webpackConfig: config, + snapshotInDocker, + skipSnapshotTools, + useLibs, + }) + ); + } - if (snapshot) { - config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "vendor", - requireModules: [ - "@nativescript/core/bundle-entry-points", - ], - projectRoot, - webpackConfig: config, - snapshotInDocker, - skipSnapshotTools, - useLibs - })); - } + if (hmr) { + config.plugins.push(new webpack.HotModuleReplacementPlugin()); + } - if (hmr) { - config.plugins.push(new webpack.HotModuleReplacementPlugin()); - } - - return config; + return config; }; diff --git a/tools/assets/App_Resources/iOS/build.xcconfig b/tools/assets/App_Resources/iOS/build.xcconfig index e77e78db9..f8e9da181 100644 --- a/tools/assets/App_Resources/iOS/build.xcconfig +++ b/tools/assets/App_Resources/iOS/build.xcconfig @@ -4,3 +4,4 @@ // To build for device with Xcode 8 you need to specify your development team. More info: https://developer.apple.com/library/prerelease/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html // DEVELOPMENT_TEAM = YOUR_TEAM_ID; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; +IPHONEOS_DEPLOYMENT_TARGET = 12.0; diff --git a/tools/scripts/run-automated.js b/tools/scripts/run-automated.js new file mode 100644 index 000000000..8c67329a1 --- /dev/null +++ b/tools/scripts/run-automated.js @@ -0,0 +1,36 @@ +/** + * Script to run the automated tests & exit after the tests are finished. + * Mainly intended to be used on CI + * + * Usage: node run-automated.js + */ +const spawn = require('child_process').spawn +const kill = require('tree-kill'); + +const spawned_process = spawn('npm', ['start', `apps.automated.${process.argv[2]}`], { + stdio: ['inherit', 'pipe', 'pipe'] +}) + +const {stdout, stderr} = spawned_process + +stdout.pipe(process.stdout) +stderr.pipe(process.stderr) + +let lineBuffer = [] + +stdout.on('data', data => { + const line = data.toString(); + + // start buffering lines when tests are complete + if(lineBuffer.length || line.includes('=== ALL TESTS COMPLETE ===')) { + lineBuffer.push(line) + } + + if(line.includes('Tests EOF!')) { + let ok = lineBuffer.join('\n').includes('OK, 0 failed') + console.log(ok ? 'Tests PASSED' : 'Tests FAILED'); + kill(spawned_process.pid) + process.exit(ok ? 0 : 1) + } +}) + diff --git a/workspace.json b/workspace.json index 7c23c1ef4..418719bf4 100644 --- a/workspace.json +++ b/workspace.json @@ -126,15 +126,15 @@ "builder": "@nrwl/workspace:run-commands", "outputs": ["dist/packages"], "options": { - "commands": [ - "npx rimraf dist/packages/core", - "./node_modules/.bin/tsc -p packages/core/tsconfig.lib.json", - "./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/**/*.d.ts\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/js-libs/**/*\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/cli-hooks/**/*.js\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/platforms/**/*\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/fetch/**/*\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/css/**/*\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/css-value/**/*\" dist", - "cp packages/core/package.json dist/packages/core", - "cp LICENSE dist/packages/core", + "commands": [ + "npx rimraf dist/packages/core", + "./node_modules/.bin/tsc -p packages/core/tsconfig.lib.json", + "./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/**/*.d.ts\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/js-libs/**/*\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/cli-hooks/**/*.js\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/platforms/**/*\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/fetch/**/*\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/css/**/*\" dist && ./node_modules/.bin/copyfiles -e \"packages/core/__tests__/**/*\" \"packages/core/css-value/**/*\" dist", + "cp packages/core/package.json dist/packages/core", + "cp LICENSE dist/packages/core", "cd dist/packages/core && npm pack && mv *.tgz .." - ], - "cwd": ".", + ], + "cwd": ".", "parallel": false } },