Compare commits

...

38 Commits

Author SHA1 Message Date
Victor Savkin 023d230a22 Release 13.2.2 2021-11-22 12:37:16 -05:00
Leosvel Pérez Espinosa fe29c88d0a fix(core): fix adding node_modules to path on windows when running migrations (#7835) 2021-11-22 12:34:40 -05:00
Jason Jean d75d8b4bc9 Release 13.2.1 2021-11-19 18:51:00 -05:00
Jason Jean 9788a7a8c3 Revert "fix(core): prevent overwriting already added tasks when adding target dependencies tasks" (#7815)
This reverts commit babcbf613e.
2021-11-19 18:46:45 -05:00
Benjamin Cabanes 6694149eb1 docs(nxdev): faster animation appearance (#7812) 2021-11-19 13:41:23 -05:00
Colum Ferry 004698f617 chore(angular): migrate angular localize (#7811) 2021-11-19 13:41:14 -05:00
Leosvel Pérez Espinosa ff12ac7bfc fix(angular): consider tailwind usage when invalidating stylesheet caching in publishable libraries (#7804) 2021-11-19 13:40:04 -05:00
Victor Savkin 275662d70a chore(repo): update the version of nx cloud 2021-11-19 13:39:10 -05:00
Colum Ferry 0076bfcd53 chore(angular): use yarn for buildable libs test (#7769)
* chore(angular): use yarn for buildable libs test

* chore(core): allow passing package manager to newProject
2021-11-19 13:26:06 -05:00
Jason Jean e9c00fe1c8 chore(repo): update nx to 13.2.0-rc.4 (#7796) 2021-11-19 13:25:27 -05:00
Jason Jean 9e2ba1eb40 Release 13.2.0 2021-11-18 17:15:37 -05:00
Ben Callaghan 1ccf1ab532 fix(core): add better error message for invalid tools tsconfig (#7792)
Co-authored-by: Ben Callaghan <bcallaghan@selectbankcard.com>
2021-11-18 16:58:41 -05:00
Juri Strumpflohner 96333fca57 fix(storybook): do not add Story args when the default value cannot be inferred (#7754) 2021-11-18 12:58:58 -05:00
Jason Jean 7e691e9fbb feat(angular): update jest-preset-angular to 11.0.0 (#7789) 2021-11-18 12:04:45 -05:00
Craigory Coppola 0a4875c083 fix(angular): fix missing null checks in v13 migrations (#7790) 2021-11-18 12:04:45 -05:00
Leosvel Pérez Espinosa 220cd014a5 fix(angular): add tailwind.js to package exports (#7785) 2021-11-18 11:06:18 -05:00
Leosvel Pérez Espinosa bd5d0d8906 fix(angular): generate ng-package.json for secondary entrypoints (#7786) 2021-11-18 11:06:18 -05:00
Colum Ferry 0b7db04902 chore(angular): bump ngrx to 13.0.0 (#7765)
* chore(angular): bump ngrx to 13.0.0

* fix(angular): add path filter to resolver for exports

* fix(testing): add mjs to jest module extensions and add dependency on resolve.exports

Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
2021-11-18 11:06:18 -05:00
Benjamin Cabanes 5a74cc00f4 docs(nxdev): higher y translation value for terminal animation (#7776) 2021-11-18 11:06:18 -05:00
Philip Fulcher 07e37a5f09 fix(dep-graph): set workspaceLayout on initGraph (#7774) 2021-11-17 17:54:41 -05:00
Leosvel Pérez Espinosa eb28deb8a8 fix(angular): fix incremental builds with angular 13 (#7770) 2021-11-17 17:54:41 -05:00
Leosvel Pérez Espinosa f636c95986 fix(devkit): handle other variants of root paths in visitNotIgnoredFiles (#7767) 2021-11-17 17:54:41 -05:00
Colum Ferry be0e5634a7 chore(angular): bump jest-preset-angular to rc4 (#7766) 2021-11-17 17:54:41 -05:00
Leosvel Pérez Espinosa f88d89047e fix(core): prevent overwriting already added tasks when adding target dependencies tasks 2021-11-17 17:54:41 -05:00
Christopher Dieringer 668770e4b6 fix(node): fix source-map-support dependency (#7728) 2021-11-17 17:53:54 -05:00
Naresh Bhatia 6f0ce741de docs(react): clean up react tutorial to match the latest version of nx (#7639) 2021-11-17 17:53:54 -05:00
Fernando Montoya b495f21345 fix(react): Fix typo (#7748) 2021-11-17 17:53:54 -05:00
Nicholas Cunningham 67de1a95b7 fix(web): add scripts default value in schema.json (#7757)
The scripts property inside project.json is not required. So if it is not provided running the build
command should not fail due to the scripts property being missing.

ISSUES CLOSED: #7178
2021-11-17 17:53:54 -05:00
Umair Hafeez 37565378dc docs(angular): update 'npm run' to 'npx nx' for affected commands (#7738)
* docs(angular): update 'npm run' to 'npx nx' for affected commands

The tutorial refers to using 'npm run' for the affected commands, which doesn't work if the
workspace is generated using yarn.

To fix that, change it to 'npx nx' so it works in all cases,
like other places in the docs.

* chore(misc): fix formatting

Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
2021-11-17 17:53:54 -05:00
Juri Strumpflohner 7a4b377889 chore(storybook): update Storybook to 6.4 RC.3 (#7755)
* chore(storybook): update Storybook to 6.4 RC.3

* chore(storybook): fix e2e test

Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
2021-11-16 17:22:07 -05:00
Leosvel Pérez Espinosa ceefe6e023 fix(misc): prevent formatting root config files twice (#7753) 2021-11-16 17:22:07 -05:00
Colum Ferry e0d9838d3d fix(angular): do not re-add transform ignore pattern (#7751) 2021-11-16 17:22:07 -05:00
Nicholas Cunningham 955d5cbbea fix(web): default react builds to production when NODE_ENV is not provided (#7727)
ISSUES CLOSED: #7410
2021-11-15 16:09:02 -05:00
Victor Savkin 552978e23e fix(core): NODE_PATH should include both workspace and tmp folders 2021-11-15 16:09:02 -05:00
Benjamin Cabanes ee9b7a3913 docs(nxdev): remove nx playbook 50% special link (#7741) 2021-11-15 16:09:02 -05:00
Benjamin Cabanes f1a99ee048 docs(nxdev): open source list on 2 columns for mobile (#7732) 2021-11-15 16:09:02 -05:00
Benjamin Cabanes e56be6c7a2 docs(nxdev): nxplaybook special offer on mobile (#7733) 2021-11-15 16:09:02 -05:00
Juri Strumpflohner 31584c83f5 feat(storybook): angular v13 and Storybook 6.4 support (#7690)
* feat(storybook): angular v13 and Storybook 6.4 support

* fixup! feat(storybook): angular v13 and Storybook 6.4 support

* fix(angular): add specific storybook prerelease for angular 13 support

* fixup! fix(angular): add specific storybook prerelease for angular 13 support

* fixup! fixup! fix(angular): add specific storybook prerelease for angular 13 support

* feat(angular): add storybook support for angular 13

* fix(angular): temporarily disable storybook tests

Co-authored-by: Colum Ferry <cferry09@gmail.com>
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
2021-11-12 22:53:27 -05:00
133 changed files with 1824 additions and 1588 deletions
+88 -292
View File
@@ -36,13 +36,6 @@ executors:
docker:
- image: cimg/node:14.17-browsers
windows:
<<: *defaults
resource_class: windows.medium
machine:
image: windows-server-2019-vs2019:stable
shell: cmd.exe
macos:
<<: *defaults
macos:
@@ -62,7 +55,7 @@ executors:
# COMMANDS
# -------------------------
commands:
run-yarn:
run-yarn-install:
parameters:
os:
type: string
@@ -82,24 +75,10 @@ commands:
- ~/.cache/yarn
install-pnpm:
parameters:
os:
type: string
steps:
- unless:
condition:
equal: [<< parameters.os >>, windows]
steps:
- run:
name: Install PNPM
command: npm install --prefix=$HOME/.local -g pnpm@6.9.1
- when:
condition:
equal: [<< parameters.os >>, windows]
steps:
- run:
name: Install PNPM
command: npm install -g pnpm@6.9.1
- run:
name: Install PNPM
command: npm install --prefix=$HOME/.local -g pnpm@6.9.1
setup:
parameters:
@@ -107,13 +86,6 @@ commands:
type: string
steps:
- checkout
- when:
condition:
equal: [<< parameters.os >>, windows]
steps:
- run: nvm install 14.17
- run: nvm use 14.17
- run: npm install -g yarn@1.22.10
- when:
condition:
equal: [<< parameters.os >>, macos]
@@ -136,13 +108,63 @@ commands:
- /usr/local/Homebrew
- ~/Library/Caches/Homebrew
- run-yarn:
os: << parameters.os >>
- install-pnpm:
- run-yarn-install:
os: << parameters.os >>
- install-pnpm
run-checks:
# -------------------------
# JOBS
# -------------------------
jobs:
# -------------------------
# JOBS: Agent
# -------------------------
agent:
parameters:
os:
type: string
default: 'linux'
pm:
type: string
default: 'pnpm'
executor: << parameters.os >>
environment:
GIT_AUTHOR_EMAIL: test@test.com
GIT_AUTHOR_NAME: Test
GIT_COMMITTER_EMAIL: test@test.com
GIT_COMMITTER_NAME: Test
NX_E2E_CI_CACHE_KEY: e2e-circleci-<< parameters.os >>
SELECTED_PM: << parameters.pm >>
NX_E2E_RUN_CYPRESS: 'false'
steps:
- run:
name: Set dynamic nx run variable
command: |
echo "export NX_RUN_GROUP=\"run-group-<< parameters.os >>-$CIRCLE_WORKFLOW_ID\";" >> $BASH_ENV
- setup:
os: << parameters.os >>
- run:
name: Agent
command: npx nx-cloud start-agent
no_output_timeout: 60m
# -------------------------
# JOBS: Main
# -------------------------
main:
executor: linux
environment:
NX_CLOUD_DISTRIBUTED_EXECUTION: 'true'
NX_E2E_CI_CACHE_KEY: e2e-circleci-linux
steps:
- run:
name: Set dynamic nx run variable
command: |
echo "export NX_RUN_GROUP=\"run-group-linux-$CIRCLE_WORKFLOW_ID\";" >> $BASH_ENV
- setup:
os: linux
- nx/set-shas:
main-branch-name: 'master'
- run:
name: Check Documentation
command: yarn documentation
@@ -158,210 +180,49 @@ commands:
- run:
name: Check Package dependencies
command: yarn depcheck
run-targets:
parameters:
run-builds:
type: string
default: 'true'
run-unit-tests:
type: string
default: 'true'
run-linting:
type: string
default: 'true'
run-e2e-tests:
type: string
default: 'true'
# Filters for tests
unit-test-filter:
type: string
default: ''
e2e-test-filter:
type: string
default: ''
exclude-projects:
type: string
default: ''
steps:
- when:
condition:
equal: [<< parameters.run-builds >>, 'true']
steps:
- run:
name: Run Builds
command: |
npx nx affected --target=build --base=$NX_BASE --head=$NX_HEAD --parallel --max-parallel=3
- when:
condition:
equal: [<< parameters.run-unit-tests >>, 'true']
steps:
- when:
condition:
equal: [<< parameters.unit-test-filter >>, '']
steps:
- run:
name: Run Unit Tests
command: |
npx nx affected --target=test --base=$NX_BASE --head=$NX_HEAD --parallel --max-parallel=2
- unless:
condition:
equal: [<< parameters.unit-test-filter >>, '']
steps:
- run:
name: Run Unit Tests with Filter "<< parameters.unit-test-filter >>"
command: |
npx nx affected --target=test --base=$NX_BASE --head=$NX_HEAD --parallel --max-parallel=2 -- --t="<< parameters.unit-test-filter >>"
- when:
condition:
equal: [<< parameters.run-linting >>, 'true']
steps:
- run:
name: Run Linting
command: |
npx nx workspace-lint
npx nx affected --target=lint --base=$NX_BASE --head=$NX_HEAD --parallel --max-parallel=4
- when:
condition:
equal: [<< parameters.run-e2e-tests >>, 'true']
steps:
- when:
condition:
equal: [<< parameters.e2e-test-filter >>, '']
steps:
- run:
name: Run E2E Tests
command: |
npx nx affected --target=e2e --base=$NX_BASE --head=$NX_HEAD --exclude=<< parameters.exclude-projects >>
no_output_timeout: 45m
- unless:
condition:
equal: [<< parameters.e2e-test-filter >>, '']
steps:
- run:
name: Run E2E Tests with Filter "<< parameters.e2e-test-filter >>"
command: |
npx nx affected --target=e2e --base=$NX_BASE --head=$NX_HEAD --exclude=<< parameters.exclude-projects >> -- --t="<< parameters.e2e-test-filter >>"
no_output_timeout: 45m
# -------------------------
# JOBS
# -------------------------
jobs:
# -------------------------
# JOBS: Agent
# -------------------------
agent:
parameters:
os:
type: string
default: 'linux'
cli:
type: string
default: ''
pm:
type: string
default: pnpm
executor: << parameters.os >>
environment:
GIT_AUTHOR_EMAIL: test@test.com
GIT_AUTHOR_NAME: Test
GIT_COMMITTER_EMAIL: test@test.com
GIT_COMMITTER_NAME: Test
NX_E2E_CI_CACHE_KEY: e2e-circleci-<< parameters.os >>-<< parameters.pm >>
SELECTED_PM: << parameters.pm >>
SELECTED_CLI: << parameters.cli >>
steps:
- run:
name: Set dynamic nx run variable
name: Run Tests
command: |
echo "export NX_RUN_GROUP=\"e2e-run-group-<< parameters.os >>-<< parameters.pm >>-$CIRCLE_WORKFLOW_ID\";" >> $BASH_ENV
- setup:
os: << parameters.os >>
npx nx affected --target=test --base=$NX_BASE --head=$NX_HEAD --parallel --max-parallel=3
- run:
name: Agent
command: npx nx-cloud start-agent
no_output_timeout: 60m
name: Run Lint
command: |
npx nx affected --target=lint --base=$NX_BASE --head=$NX_HEAD --parallel --max-parallel=3
- run:
name: Run Builds
command: |
npx nx affected --target=build --base=$NX_BASE --head=$NX_HEAD --parallel --max-parallel=3
- run:
name: Run E2E Tests
command: |
npx nx affected --target=e2e --base=$NX_BASE --head=$NX_HEAD --exclude=e2e-react-native,e2e-detox --parallel --max-parallel=1
no_output_timeout: 45m
- run:
name: Stop All Running Agents for This CI Run
command: npx nx-cloud stop-all-agents
# -------------------------
# JOBS: Main
# JOBS: Main-MacOS
# -------------------------
main:
parameters:
# -------------------------
# Environment setup
# -------------------------
os:
type: string
default: 'linux'
cli:
type: string
default: ''
pm:
type: string
default: pnpm
# -------------------------
# Flags
# -------------------------
run-checks:
type: string
default: 'true'
run-builds:
type: string
default: 'true'
run-unit-tests:
type: string
default: 'true'
run-linting:
type: string
default: 'true'
run-e2e-tests:
type: string
default: 'true'
run-cypress-tests:
type: string
default: 'false'
# -------------------------
# Filters for tests
# -------------------------
unit-test-filter:
type: string
default: ''
e2e-test-filter:
type: string
default: ''
exclude-projects:
type: string
default: ''
executor: << parameters.os >>
mainmacos:
executor: macos
environment:
NX_CLOUD_DISTRIBUTED_EXECUTION: 'true'
SELECTED_CLI: << parameters.cli >>
SELECTED_PM: << parameters.pm >>
NX_E2E_CI_CACHE_KEY: e2e-circleci-<< parameters.os >>-<< parameters.pm >>
NX_E2E_RUN_CYPRESS: << parameters.run-cypress-tests >>
NX_E2E_CI_CACHE_KEY: e2e-circleci-macos
steps:
- run:
name: Set dynamic nx run variable
command: |
echo "export NX_RUN_GROUP=\"e2e-run-group-<< parameters.os >>-<< parameters.pm >>-$CIRCLE_WORKFLOW_ID\";" >> $BASH_ENV
echo "export NX_RUN_GROUP=\"run-group-macos-$CIRCLE_WORKFLOW_ID\";" >> $BASH_ENV
- setup:
os: << parameters.os >>
os: macos
- nx/set-shas:
main-branch-name: 'master'
- when:
condition:
equal: [<< parameters.run-checks >>, 'true']
steps:
- run-checks
- run-targets:
run-builds: << parameters.run-builds >>
run-unit-tests: << parameters.run-unit-tests >>
run-linting: << parameters.run-linting >>
run-e2e-tests: << parameters.run-e2e-tests >>
unit-test-filter: << parameters.unit-test-filter >>
e2e-test-filter: << parameters.e2e-test-filter >>
exclude-projects: << parameters.exclude-projects >>
- run:
name: Run E2E Tests
command: |
npx nx affected --target=e2e --base=$NX_BASE --head=$NX_HEAD --exclude=e2e-js,e2e-next,e2e-gatsby,e2e-workspace-create,e2e-workspace-integrations,e2e-workspace-core,e2e-react,e2e-web,e2e-angular-extensions,e2e-angular-core,e2e-cli,e2e-nx-plugin,e2e-storybook,e2e-cypress,e2e-node,e2e-linter,e2e-jest --max-parallel=1
no_output_timeout: 45m
- run:
name: Stop All Running Agents for This CI Run
command: npx nx-cloud stop-all-agents
@@ -403,70 +264,5 @@ workflows:
# -------------------------
- main:
name: pull-request
run-checks: 'true'
exclude-projects: 'e2e-react-native,e2e-detox'
filters:
branches:
ignore: master
- main:
name: pull-request-osx
pm: 'npm'
os: 'macos'
run-checks: 'false'
run-builds: 'false'
run-unit-tests: 'false'
run-linting: 'false'
e2e-test-filter: 'MACOS-Tests'
exclude-projects: 'e2e-next,e2e-gatsby,e2e-workspace-create,e2e-workspace-integrations,e2e-workspace-core,e2e-react,e2e-web,e2e-angular-extensions,e2e-angular-core,e2e-cli,e2e-nx-plugin,e2e-storybook,e2e-cypress,e2e-node,e2e-linter,e2e-jest'
filters:
branches:
ignore: master
# - main:
# name: pull-request-android
# pm: 'npm'
# os: 'android'
# run-checks: 'false'
# run-builds: 'false'
# run-unit-tests: 'false'
# run-linting: 'false'
# e2e-test-filter: 'Android-Tests'
# filters:
# branches:
# ignore: master
# -------------------------
# Commit to master
# -------------------------
- main:
name: commit-to-master
run-cypress-tests: 'true'
exclude-projects: 'e2e-react-native,e2e-detox,e2e-gatsby'
filters:
branches:
only: master
- main:
name: commit-to-master-osx
pm: 'npm'
os: 'macos'
run-checks: 'false'
run-builds: 'false'
run-unit-tests: 'false'
run-linting: 'false'
e2e-test-filter: 'MACOS-Tests'
run-cypress-tests: 'true'
exclude-projects: 'e2e-next,e2e-gatsby,e2e-workspace-create,e2e-workspace-integrations,e2e-workspace-core,e2e-react,e2e-web,e2e-angular-extensions,e2e-angular-core,e2e-cli,e2e-nx-plugin,e2e-storybook,e2e-cypress,e2e-node,e2e-linter,e2e-jest'
filters:
branches:
only: master
# - main:
# name: commit-to-master-android
# pm: 'npm'
# os: 'android'
# run-checks: 'false'
# run-builds: 'false'
# run-unit-tests: 'false'
# run-linting: 'false'
# e2e-test-filter: 'Android-Tests'
# run-cypress-tests: 'true'
# filters:
# branches:
# only: master
- mainmacos:
name: pull-request-macos
@@ -46,6 +46,7 @@ export const depGraphMachine = Machine<
ctx.projects = event.projects;
ctx.affectedProjects = event.affectedProjects;
ctx.dependencies = event.dependencies;
ctx.workspaceLayout = event.workspaceLayout;
}),
},
@@ -78,7 +78,7 @@ export const mockDependencies: Record<string, ProjectGraphDependency[]> = {
describe('dep-graph machine', () => {
describe('initGraph', () => {
it('should set projects and dependencies', () => {
it('should set projects, dependencies, and workspaceLayout', () => {
const result = depGraphMachine.transition(depGraphMachine.initialState, {
type: 'initGraph',
projects: mockProjects,
@@ -88,6 +88,10 @@ describe('dep-graph machine', () => {
});
expect(result.context.projects).toEqual(mockProjects);
expect(result.context.dependencies).toEqual(mockDependencies);
expect(result.context.workspaceLayout).toEqual({
appsDir: 'apps',
libsDir: 'libs',
});
});
it('should start with no projects selected', () => {
@@ -23,15 +23,15 @@ git checkout -b testbranch
Run the command to see affected apps.
```sh
npm run affected:apps
npx nx affected:apps
```
You should see `todos` printed out. The `affected:apps` looks at what you have changed and uses the dependency graph to figure out which apps can be affected by this change.
Run the command to see affected libraries
```
npm run affected:libs
```sh
npx nx affected:libs
```
You should see `ui` printed out. This command works similarly, but instead of printing the affected apps, it prints the affected libs.
@@ -67,7 +67,7 @@ Note that Nx only tried to retest `ui` and `todos`. It didn't retest `api` or `d
Run the command to retest the failed projects.
```sh
npm run affected:test -- --only-failed
npx nx affected:test -- --only-failed
```
## Affected:
+2 -2
View File
@@ -58,7 +58,7 @@
"id": "05-add-node-app"
},
{
"name": "6 - Configure Proxy",
"name": "6 - Proxy Configuration",
"id": "06-proxy"
},
{
@@ -1370,7 +1370,7 @@
"id": "05-add-node-app"
},
{
"name": "6 - Configure Proxy",
"name": "6 - Proxy Configuration",
"id": "06-proxy"
},
{
+4 -3
View File
@@ -25,9 +25,9 @@ Application name todos
Default stylesheet format CSS
```
> You can also choose to add [Nx Cloud](https://nx.app), but its not required for the tutorial.
Enter the indicated answers.
When asked about 'preset', select `react`, and `todos` for the app name.
> You can also choose to add [Nx Cloud](https://nx.app), but its not required for the tutorial.
```treeview
myorg/
@@ -46,6 +46,7 @@ myorg/
│ │ ├── .browserslistrc
│ │ ├── .eslintrc.json
│ │ ├── jest.config.js
│ │ ├── project.json
│ │ ├── tsconfig.app.json
│ │ ├── tsconfig.json
│ │ └── tsconfig.spec.json
@@ -63,7 +64,7 @@ myorg/
│ │ └── index.ts
│ ├── .eslintrc.json
│ ├── cypress.json
│ ├── tsconfig.e2e.json
│ ├── project.json
│ └── tsconfig.json
├── libs/
├── tools/
+15 -8
View File
@@ -11,12 +11,13 @@ Nx is an open platform with plugins for many modern tools and frameworks. **To s
```bash
> NX Installed plugins:
@nrwl/cypress (executors,generators)
@nrwl/jest (executors,generators)
@nrwl/linter (builders)
@nrwl/cypress (builders,generators)
@nrwl/jest (builders,generators)
@nrwl/linter (builders,generators)
@nrwl/react (generators)
@nrwl/web (executors,generators)
@nrwl/workspace (executors,generators)
@nrwl/storybook (builders,generators)
@nrwl/web (builders,generators)
@nrwl/workspace (builders,generators)
> NX Also available:
@@ -27,7 +28,6 @@ Nx is an open platform with plugins for many modern tools and frameworks. **To s
@nrwl/next (executors,generators)
@nrwl/node (executors,generators)
@nrwl/nx-plugin (executors,generators)
@nrwl/storybook (executors,generators)
> NX Community plugins:
@@ -72,7 +72,10 @@ After this is done, you should see something like this:
```treeview
myorg/
├── apps/
├── todos/
   ├── todos/
│   │   ├── src/
│   │   ├── project.json
│   │   └── proxy.conf.json
│ ├── todos-e2e/
│ └── api/
│ ├── src/
@@ -83,7 +86,7 @@ myorg/
│ │ │ └── environment.prod.ts
│ │ └── main.ts
│ ├── jest.conf.js
│ ├── proxy.conf.json
│ ├── project.json
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ └── tsconfig.spec.json
@@ -147,3 +150,7 @@ const server = app.listen(port, () => {
});
server.on('error', console.error);
```
**Now run `npx nx serve api` to run the api server**
Refresh the application in the browser. The React app is now able to fetch and create todos by calling the API.
+12 -12
View File
@@ -1,4 +1,4 @@
# React Nx Tutorial - Step 6: Proxy
# React Nx Tutorial - Step 6: Proxy Configuration
<iframe width="560" height="315" src="https://www.youtube.com/embed/xfvCz-yLeEw" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
@@ -6,28 +6,28 @@ You passed `--frontendProject=todos` when creating the node application. What di
It created a proxy configuration that allows the React application to talk to the API in development.
**To see how it works, open `workspace.json` and find the `serve` target of the todos app.**
**To see how it works, open `apps/todos/project.json` and find the `serve` target.**
```json
{
"serve": {
"builder": "@nrwl/web:dev-server",
"executor": "@nrwl/web:dev-server",
"options": {
"buildTarget": "todos:build",
"hmr": true,
"proxyConfig": "apps/todos/proxy.conf.json"
},
"configurations": {
"production": {
"buildTarget": "todos:build:production"
"buildTarget": "todos:build:production",
"hmr": false
}
}
}
}
```
**Note the `proxyConfig` property.**
**Now open `proxy.conf.json`:**
Note the `proxyConfig` property which points to `apps/todos/proxy.conf.json`. Open this file.
```json
{
@@ -40,11 +40,11 @@ It created a proxy configuration that allows the React application to talk to th
This configuration tells `npx nx serve` to forward all requests starting with `/api` to the process listening on port `3333`.
## Workspace.json, Targets, Builders
## Project.json, Targets, Executors
You configure your workspaces in `workspace.json`. This file contains the workspace projects with their architect targets. For instance, `todos` has the `build`, `serve`, `lint`, and `test` targets. This means that you can run `npx nx build todos`, `npx nx serve todos`, etc..
You configure your apps in `apps/[app-name]/project.json`. Open `apps/todos/project.json` to see an example. This file contains configuration for the todos app. For instance, you can see the `build`, `serve`, `lint`, and `test` targets. This means that you can run `npx nx build todos`, `npx nx serve todos`, etc..
Every target uses a builder which actually runs this target. So targets are analogous to typed npm scripts, and builders are analogous to typed shell scripts.
Every target uses an executor which actually runs this target. So targets are analogous to typed npm scripts, and executors are analogous to typed shell scripts.
**Why not use shell scripts and npm scripts directly?**
@@ -54,7 +54,7 @@ There are a lot of advantages to providing additional metadata to the build tool
npx nx run todos:serve [options,...]
Options:
--buildTarget Target which builds the application`
--buildTarget Target which builds the application
--port Port to listen on. (default: 4200)
--host Host to listen on. (default: localhost)
--ssl Serve using HTTPS.
@@ -73,4 +73,4 @@ Options:
It helps with good editor integration (see [VSCode Support](/{{framework}}/getting-started/console#nx-console-for-vscode)).
But, most importantly, it provides a holistic dev experience regardless of the tools used, and enables advanced build features like distributed computation caching and distributed builds).
But, most importantly, it provides a holistic dev experience regardless of the tools used, and enables advanced build features like distributed computation caching and distributed builds.
+2 -1
View File
@@ -25,8 +25,9 @@ myorg/
│ │ │ └── data.ts
│ │ └── index.ts
│ ├── jest.conf.js
│ ├── tsconfig.app.json
│ ├── project.json
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ └── tsconfig.spec.json
├── tools/
├── nx.json
+26 -22
View File
@@ -31,17 +31,18 @@ myorg/
│ └── ui/
│ ├── src/
│ │ ├── lib/
│ │ │ ── ui/
│ │ │ ├── ui.css
│ │ │ ├── ui.spec.tsx
│ │ │ └── ui.tsx
│ │ │ ── ui.css
│ │ │ ├── ui.spec.tsx
│ │ │ └── ui.tsx
│ │ └── index.ts
│ ├── jest.conf.js
│ ├── tsconfig.app.json
│ ├── project.json
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ └── tsconfig.spec.json
├── tools/
├── nx.json
├── workspace.json
├── package.json
└── tsconfig.base.json
```
@@ -49,19 +50,18 @@ myorg/
The `libs/ui/src/lib/ui.tsx` file looks like this:
```typescript
import React from 'react';
import './ui.css';
import './ui.module.css';
/* eslint-disable-next-line */
export interface UiProps {}
export const Ui = (props: UiProps) => {
export function Ui(props: UiProps) {
return (
<div>
<h1>Welcome to ui!</h1>
<h1>Welcome to Ui!</h1>
</div>
);
};
}
export default Ui;
```
@@ -87,18 +87,18 @@ myorg/
│ └── ui/
│ ├── src/
│ │ ├── lib/
│ │ │ ├── ui/
│ │ │ │ ├── ui.css
│ │ │ │ ├── ui.spec.tsx
│ │ │ │ └── ui.tsx
│ │ │ └── todos/
│ │ │ ├── todos.css
│ │ │ ├── todos.spec.tsx
│ │ │ └── todos.tsx
│ │ │ ├── todos.css
│ │ │ ├── todos.spec.tsx
│ │ │ └── todos.tsx
│ │ │ ├── ui.css
│ │ │ ├── ui.spec.tsx
│ │ │ └── ui.tsx
│ │ └── index.ts
│ ├── jest.conf.js
│ ├── tsconfig.app.json
│ ├── project.json
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ └── tsconfig.spec.json
├── tools/
├── workspace.json
@@ -110,10 +110,14 @@ myorg/
**Implement the Todos component.**
```typescript
import React from 'react';
import { Todo } from '@myorg/data';
import './todos.module.css';
export const Todos = (props: { todos: Todo[] }) => {
export interface TodosProps {
todos: Todo[];
}
export function Todos(props: TodosProps) {
return (
<ul>
{props.todos.map((t) => (
@@ -121,7 +125,7 @@ export const Todos = (props: { todos: Todo[] }) => {
))}
</ul>
);
};
}
export default Todos;
```
+8
View File
@@ -7,3 +7,11 @@ An Nx workspace can contain dozens or hundreds of applications and libraries. As
Previously, some senior architect would create an ad-hoc dependency diagram and upload it to a corporate wiki. The diagram is not correct even on Day 1 and gets more and more out of sync with every passing day.
With Nx, you can do better than that.
Run
```bash
npx nx dep-graph
```
The dependency graph page opens in a new browser window. Click on "Show all projects" to see all the apps and libraries in the workspace.
@@ -54,41 +54,4 @@ Nx read the output from cache instead of running the command for 1 out of 2 proj
Nx built `api` and retrieved `todos` from its computation cache. Read more about the cache [here](/{{framework}}/core-extended/computation-caching).
## --with-deps
As we saw already, Nx is smart, so it knows how applications and libraries in the workspace depend on each other.
**Run `npx nx lint todos --with-deps`, and you see that Nx lints both the `todos` app and the libraries it depends on.**
```bash
> NX Running target lint for project todos and its 2 deps.
———————————————————————————————————————————————
> npx nx run todos:lint
Linting "todos"...
All files pass linting.
> npx nx run ui:lint
Linting "ui"...
All files pass linting.
> npx nx run data:lint
Linting "data"...
All files pass linting.
———————————————————————————————————————————————
> NX SUCCESS Running target "lint" succeeded
```
> Add --parallel to any command, and Nx does most of the work in parallel.
@@ -4,7 +4,7 @@
In addition to supporting computation caching, Nx scales your development by doing code change analysis to see what is affected by a particular pull request.
**Commit all the changes in the repo**:
**Commit all the changes you have made so far**:
```bash
git add .
@@ -12,13 +12,17 @@ git commit -am 'init'
git checkout -b testbranch
```
**Open `libs/ui/src/lib/todos/todos.tsx` and change the component:**
**Open `libs/ui/src/lib/todos/todos.tsx` and change the component by updating the `<li>` content to `{t.title}!!`:**
```typescript
import React from 'react';
import { Todo } from '@myorg/data';
import './todos.module.css';
export const Todos = (props: { todos: Todo[] }) => {
export interface TodosProps {
todos: Todo[];
}
export function Todos(props: TodosProps) {
return (
<ul>
{props.todos.map((t) => (
@@ -26,7 +30,7 @@ export const Todos = (props: { todos: Todo[] }) => {
))}
</ul>
);
};
}
export default Todos;
```
+1 -1
View File
@@ -84,7 +84,7 @@ React applications are built using the executors from the `@nrwl/web` plugin.
## Generators
- [application](/{{framework}}/react/application) - Create an React application
- [component](/{{framework}}/react/component) - Create an React library
- [component](/{{framework}}/react/component) - Create an React component
- [library](/{{framework}}/react/library) - Create an React library
- [redux](/{{framework}}/react/redux) - Generate a Redux slice for a project
- [storybook-configuration](/{{framework}}/react/storybook-configuration) - Set up Storybook for a react library
+41 -42
View File
@@ -23,27 +23,29 @@ describe('Angular Package', () => {
let buildableLib;
let proj: string;
// This fails with pnpm due to incompatibilities with ngcc.
// Since this suite has a single test, we wrap everything to avoid the hooks to run and
// waste time.
if (getSelectedPackageManager() !== 'pnpm') {
beforeEach(() => {
app = uniq('app');
buildableLib = uniq('buildlib1');
beforeEach(() => {
app = uniq('app');
buildableLib = uniq('buildlib1');
proj = newProject();
// This fails with pnpm due to incompatibilities with ngcc.
// Since this suite has a single test, we wrap everything to avoid the hooks to run and
// waste time.
// therefore switch to yarn
runCLI(
`generate @nrwl/angular:app ${app} --style=css --no-interactive`
);
runCLI(
`generate @nrwl/angular:library ${buildableLib} --buildable=true --no-interactive`
);
proj =
getSelectedPackageManager() === 'pnpm'
? newProject({ packageManager: 'yarn' })
: newProject();
// update the app module to include a ref to the buildable lib
updateFile(
`apps/${app}/src/app/app.module.ts`,
`
runCLI(`generate @nrwl/angular:app ${app} --style=css --no-interactive`);
runCLI(
`generate @nrwl/angular:library ${buildableLib} --buildable=true --no-interactive`
);
// update the app module to include a ref to the buildable lib
updateFile(
`apps/${app}/src/app/app.module.ts`,
`
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {${
@@ -60,34 +62,31 @@ describe('Angular Package', () => {
})
export class AppModule {}
`
);
);
// update the angular.json
const workspaceJson = readJson(`angular.json`);
workspaceJson.projects[app].architect.build.builder =
'@nrwl/angular:webpack-browser';
updateFile('angular.json', JSON.stringify(workspaceJson, null, 2));
});
// update the angular.json
const workspaceJson = readJson(`angular.json`);
workspaceJson.projects[app].architect.build.builder =
'@nrwl/angular:webpack-browser';
updateFile('angular.json', JSON.stringify(workspaceJson, null, 2));
});
afterEach(() => removeProject({ onlyOnCI: true }));
afterEach(() => removeProject({ onlyOnCI: true }));
it('should build the dependent buildable lib as well as the app', () => {
const libOutput = runCLI(
`build ${app} --with-deps --configuration=development`
);
expect(libOutput).toContain(
`Building entry point '@${proj}/${buildableLib}'`
);
expect(libOutput).toContain(`nx run ${app}:build:development`);
it('should build the dependent buildable lib as well as the app', () => {
const libOutput = runCLI(
`build ${app} --with-deps --configuration=development`
);
expect(libOutput).toContain(
`Building entry point '@${proj}/${buildableLib}'`
);
expect(libOutput).toContain(`nx run ${app}:build:development`);
// to proof it has been built from source the "main.js" should actually contain
// the path to dist
const mainBundle = readFile(`dist/apps/${app}/main.js`);
expect(mainBundle).toContain(`dist/libs/${buildableLib}`);
});
} else {
it('Skip tests with pnpm', () => {});
}
// to proof it has been built from source the "main.js" should actually contain
// the path to dist
const mainBundle = readFile(`dist/apps/${app}/main.js`);
expect(mainBundle).toContain(`dist/libs/${buildableLib}`);
});
});
});
@@ -36,7 +36,12 @@ describe('Angular Package', () => {
childLib = uniq('childlib');
childLib2 = uniq('childlib2');
proj = newProject();
// These fail with pnpm due to incompatibilities with ngcc for buildable libraries.
// therefore switch to yarn
proj =
getSelectedPackageManager() === 'pnpm' && testConfig !== 'publishable'
? newProject({ packageManager: 'yarn' })
: newProject();
if (testConfig === 'buildable') {
runCLI(
@@ -136,43 +141,33 @@ describe('Angular Package', () => {
afterEach(() => removeProject({ onlyOnCI: true }));
it('empty test to make jest happy', () => {});
it('should build the library when it does not have any deps', () => {
runCLI(`build ${childLib}`);
// These fail with pnpm due to incompatibilities with ngcc for buildable libraries.
if (
getSelectedPackageManager() !== 'pnpm' ||
testConfig === 'publishable'
) {
it('should build the library when it does not have any deps', () => {
runCLI(`build ${childLib}`);
checkFilesExist(`dist/libs/${childLib}/package.json`);
});
checkFilesExist(`dist/libs/${childLib}/package.json`);
});
it('should properly add references to any dependency into the parent package.json', () => {
runCLI(`build ${childLib}`);
runCLI(`build ${childLib2}`);
runCLI(`build ${parentLib}`);
it('should properly add references to any dependency into the parent package.json', () => {
runCLI(`build ${childLib}`);
runCLI(`build ${childLib2}`);
runCLI(`build ${parentLib}`);
checkFilesExist(
`dist/libs/${childLib}/package.json`,
`dist/libs/${childLib2}/package.json`,
`dist/libs/${parentLib}/package.json`
);
checkFilesExist(
`dist/libs/${childLib}/package.json`,
`dist/libs/${childLib2}/package.json`,
`dist/libs/${parentLib}/package.json`
);
const jsonFile = readJson(`dist/libs/${parentLib}/package.json`);
const jsonFile = readJson(`dist/libs/${parentLib}/package.json`);
expect(jsonFile.dependencies['tslib']).toMatch(/\^2\.\d+\.\d+/); // match any ^2.x.x
expect(
jsonFile.peerDependencies[`@${proj}/${childLib}`]
).toBeDefined();
expect(
jsonFile.peerDependencies[`@${proj}/${childLib2}`]
).toBeDefined();
expect(jsonFile.peerDependencies['@angular/common']).toBeDefined();
expect(jsonFile.peerDependencies['@angular/core']).toBeDefined();
});
}
expect(jsonFile.dependencies['tslib']).toMatch(/\^2\.\d+\.\d+/); // match any ^2.x.x
expect(jsonFile.peerDependencies[`@${proj}/${childLib}`]).toBeDefined();
expect(
jsonFile.peerDependencies[`@${proj}/${childLib2}`]
).toBeDefined();
expect(jsonFile.peerDependencies['@angular/common']).toBeDefined();
expect(jsonFile.peerDependencies['@angular/core']).toBeDefined();
});
});
});
-8
View File
@@ -10,14 +10,6 @@ import {
} from '@nrwl/e2e/utils';
describe('Angular Package', () => {
// TODO(coly010): remove when ngrx 13 (with ivy) releases
// Run Tests with Yarn then reset back
const previousPackageRunner = process.env.SELECTED_PM;
process.env.SELECTED_PM = 'yarn';
afterAll(() => {
process.env.SELECTED_PM = previousPackageRunner;
});
describe('ngrx', () => {
beforeAll(() => newProject());
afterAll(() => removeProject({ onlyOnCI: true }));
+3 -7
View File
@@ -15,8 +15,7 @@ import {
import { writeFileSync } from 'fs';
describe('Angular Package', () => {
// TODO(juristr): Re-enable these when storybook supports Angular 13
xdescribe('storybook schematics', () => {
describe('storybook schematics', () => {
let proj: string;
beforeEach(() => (proj = newProject()));
@@ -59,7 +58,7 @@ describe('Angular Package', () => {
});
describe('build storybook', () => {
it('should execute e2e tests using Cypress running against Storybook', async () => {
xit('should execute e2e tests using Cypress running against Storybook', async () => {
if (isNotWindows()) {
const myapp = uniq('myapp');
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
@@ -101,7 +100,7 @@ describe('Angular Package', () => {
writeFileSync(
tmpProjPath(`libs/${myReactLib}/src/lib/button.stories.tsx`),
`
import { Story, Meta } from '@storybook/react';
import { Story, Meta } from '@storybook/react';
import { Button, ButtonProps } from './button';
export default {
@@ -193,9 +192,6 @@ describe('Angular Package', () => {
runCLI(`run ${myAngularLib}:build-storybook`);
checkFilesExist(`dist/storybook/${myAngularLib}/index.html`);
expect(
readFile(`dist/storybook/${myAngularLib}/index.html`)
).toContain(`<title>Storybook</title>`);
}
}, 1000000);
+9 -4
View File
@@ -154,7 +154,11 @@ export function packageInstall(
) {
const cwd = projName ? `${e2eCwd}/${projName}` : tmpProjPath();
const pm = getPackageManagerCommand({ path: cwd });
const install = execSync(`${pm.addDev} ${pkg}@${version}`, {
const pkgsWithVersions = pkg
.split(' ')
.map((pgk) => `${pgk}@${version}`)
.join(' ');
const install = execSync(`${pm.addDev} ${pkgsWithVersions}`, {
cwd,
stdio: [0, 1, 2],
env: process.env,
@@ -183,9 +187,10 @@ export function getSelectedPackageManager(): 'npm' | 'yarn' | 'pnpm' {
* Sets up a new project in the temporary project path
* for the currently selected CLI.
*/
export function newProject({ name = uniq('proj') } = {}): string {
const packageManager = getSelectedPackageManager();
export function newProject({
name = uniq('proj'),
packageManager = getSelectedPackageManager(),
} = {}): string {
try {
const useBackupProject = packageManager !== 'pnpm';
const projScope = useBackupProject ? 'proj' : name;
+4 -1
View File
@@ -1,6 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": { "outDir": "../../dist/out-tsc", "types": ["node"] },
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
+4 -1
View File
@@ -1,6 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": { "outDir": "../../dist/out-tsc", "types": ["node"] },
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
@@ -1,6 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": { "outDir": "../../dist/out-tsc", "types": ["node"] },
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/next/typings/image.d.ts"
+4 -1
View File
@@ -1,6 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": { "outDir": "../../dist/out-tsc", "types": ["node"] },
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
@@ -1,6 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": { "outDir": "../../dist/out-tsc", "types": ["node"] },
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/next/typings/image.d.ts"
+1 -1
View File
@@ -8,6 +8,6 @@
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*.spec.tsx", "**/*.test.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}
+4
View File
@@ -7,9 +7,13 @@
},
"include": [
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx",
"**/*.d.ts"
]
}
+1 -1
View File
@@ -26,7 +26,7 @@ export function AffectedCommand(): ReactComponentElement<any> {
},
};
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
+1 -1
View File
@@ -26,7 +26,7 @@ export function CloudSupport(): ReactComponentElement<any> {
},
};
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
+1 -1
View File
@@ -25,7 +25,7 @@ export function DependencyGraph(): ReactComponentElement<any> {
},
};
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
@@ -169,7 +169,7 @@ export function EcosystemFeatures(): ReactComponentElement<any> {
},
};
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
+1 -1
View File
@@ -5,7 +5,7 @@ import { useInView } from 'react-intersection-observer';
export function EggheadCourses(): ReactComponentElement<any> {
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
@@ -164,7 +164,7 @@ export function ExperienceFeatures(): ReactComponentElement<any> {
},
};
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
+1 -1
View File
@@ -170,7 +170,7 @@ export function MonorepoFeatures(): ReactComponentElement<any> {
},
};
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
+1 -14
View File
@@ -5,7 +5,7 @@ import { useInView } from 'react-intersection-observer';
export function NxPlaybook(): ReactComponentElement<any> {
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
@@ -33,19 +33,6 @@ export function NxPlaybook(): ReactComponentElement<any> {
>
<div className="pt-10 pb-12 px-6 sm:pt-16 sm:px-16 lg:py-16 lg:pr-0 xl:py-20 xl:px-20">
<div className="lg:self-center relative">
<Link href="https://nxplaybook.com/p/advanced-nx-workspaces?utm_source=nx.dev">
<a
rel="nofollow"
target="_blank"
className="absolute -top-12 left-0 bg-blue-nx-dark bg-opacity-25 shadow-inner inline-flex items-center px-3 py-1 rounded-full text-xs font-medium text-gray-100 group hover:text-white hover:bg-green-nx-base transition"
>
<span className="-ml-0.5 mr-2 relative inline-flex justify-center items-center h-4 w-4">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-nx-base group-hover:bg-blue-nx-dark opacity-75 transtion" />
<span className="inline-flex h-2 w-2 rounded-full bg-green-nx-base group-hover:bg-blue-nx-dark transition" />
</span>
Get 50% off until November 14th, 2021
</a>
</Link>
<h2 className="text-3xl font-extrabold text-white sm:text-4xl">
<span className="block">Premium courses</span>
<span className="block">to know everything</span>
+1 -1
View File
@@ -74,7 +74,7 @@ export function OpenPlatform(): ReactComponentElement<any> {
},
};
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
@@ -237,7 +237,7 @@ export function OpenSourceProjects(): ReactComponentElement<any> {
}),
};
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
@@ -265,28 +265,26 @@ export function OpenSourceProjects(): ReactComponentElement<any> {
}}
className="lg:mx-auto lg:max-w-7xl p-4 flex"
>
<div className="rounded-lg bg-gray-200 overflow-hidden shadow divide-y divide-gray-200 sm:divide-y-0 sm:grid sm:grid-cols-2 sm:gap-px">
<div className="w-full rounded-lg bg-gray-200 overflow-hidden shadow divide-y divide-gray-200 divide-y-0 grid grid-cols-2 gap-px">
{projectList.map((project, index: number) => (
<motion.div
key={project.title}
key={project.title + '-' + index}
custom={0.12 * index + 0.24}
variants={opacityTranslateXVariant}
className={cx(
index === 0
? 'rounded-tl-lg rounded-tr-lg sm:rounded-tr-none'
: '',
index === 0 ? 'rounded-tl-lg' : '',
index === 1 ? 'sm:rounded-tr-lg' : '',
index === projectList.length - 2 ? 'sm:rounded-bl-lg' : '',
index === projectList.length - 2 ? 'rounded-bl-lg' : '',
index === projectList.length - 1
? 'rounded-bl-lg rounded-br-lg sm:rounded-bl-none'
? 'rounded-br-lg rounded-bl-none'
: '',
'relative group bg-white p-6 focus-within:ring-2 focus-within:ring-inset focus-within:ring-blue-nx-base'
'relative w-full group bg-white p-6 focus-within:ring-2 focus-within:ring-inset focus-within:ring-blue-nx-base'
)}
>
<div>
<span className="rounded-lg inline-flex">{project.icon}</span>
</div>
<div className="mt-2">
<div className="sm:mt-2">
<h3 className="text-lg font-medium">
<Link href={project.href}>
<a
@@ -300,7 +298,7 @@ export function OpenSourceProjects(): ReactComponentElement<any> {
</a>
</Link>
</h3>
<p className="mt-2 text-sm text-gray-400">
<p className="mt-2 hidden sm:block text-sm text-gray-400">
{project.description}
</p>
</div>
+1 -1
View File
@@ -54,7 +54,7 @@ export function Performance(): ReactComponentElement<any> {
},
};
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
+1 -1
View File
@@ -26,7 +26,7 @@ export function VscodePlugin(): ReactComponentElement<any> {
},
};
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
+1 -1
View File
@@ -5,7 +5,7 @@ import { useInView } from 'react-intersection-observer';
export function YoutubeChannel(): ReactComponentElement<any> {
const controls = useAnimation();
const [ref, inView] = useInView({ threshold: 0.5, triggerOnce: true });
const [ref, inView] = useInView({ triggerOnce: true });
useEffect(() => {
if (!inView) return;
+1 -1
View File
@@ -9,6 +9,6 @@
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*.spec.tsx", "**/*.test.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}
+4
View File
@@ -7,9 +7,13 @@
},
"include": [
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx",
"**/*.d.ts"
]
}
@@ -89,7 +89,7 @@ export function NpxCreateNxWorkspace() {
transition: { ease: 'easeOut', duration: 0.24 },
});
return await wrapper.start({
y: -82,
y: -100,
transition: { ease: 'easeOut', duration: 0.24 },
});
};
+4 -1
View File
@@ -1,6 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": { "outDir": "../../../dist/out-tsc", "types": ["node"] },
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../../node_modules/@nrwl/next/typings/image.d.ts"
+1 -4
View File
@@ -23,10 +23,7 @@
"sitemap"
],
"useDaemonProcess": true,
"runtimeCacheInputs": [
"echo $SELECTED_CLI",
"echo $NX_E2E_CI_CACHE_KEY"
],
"runtimeCacheInputs": ["echo $SELECTED_CLI", "echo $E2E_CI_CACHE_KEY"],
"cacheDirectory": "/tmp/nx-cache"
}
}
+26 -26
View File
@@ -1,6 +1,6 @@
{
"name": "@nrwl/nx-source",
"version": "13.1.3",
"version": "13.2.2",
"description": "Smart, Extensible Build Framework",
"homepage": "https://nx.dev",
"private": true,
@@ -54,25 +54,25 @@
"@nestjs/schematics": "^8.0.0",
"@nestjs/swagger": "^5.0.9",
"@nestjs/testing": "^8.0.0",
"@ngrx/component-store": "12.5.1",
"@ngrx/effects": "12.5.1",
"@ngrx/entity": "12.5.1",
"@ngrx/router-store": "12.5.1",
"@ngrx/schematics": "12.5.1",
"@ngrx/store": "12.5.1",
"@ngrx/store-devtools": "12.5.1",
"@nrwl/cli": "13.2.0-beta.5",
"@nrwl/cypress": "13.2.0-beta.5",
"@nrwl/eslint-plugin-nx": "13.2.0-beta.5",
"@nrwl/jest": "13.2.0-beta.5",
"@nrwl/linter": "13.2.0-beta.5",
"@nrwl/next": "13.2.0-beta.5",
"@nrwl/node": "13.2.0-beta.5",
"@nrwl/nx-cloud": "12.5.2",
"@nrwl/react": "13.2.0-beta.5",
"@nrwl/tao": "13.2.0-beta.5",
"@nrwl/web": "13.2.0-beta.5",
"@nrwl/workspace": "13.2.0-beta.5",
"@ngrx/component-store": "~13.0.0",
"@ngrx/effects": "~13.0.0",
"@ngrx/entity": "~13.0.0",
"@ngrx/router-store": "~13.0.0",
"@ngrx/schematics": "~13.0.0",
"@ngrx/store": "~13.0.0",
"@ngrx/store-devtools": "~13.0.0",
"@nrwl/cli": "13.2.0-rc.4",
"@nrwl/cypress": "13.2.0-rc.4",
"@nrwl/eslint-plugin-nx": "13.2.0-rc.4",
"@nrwl/jest": "13.2.0-rc.4",
"@nrwl/linter": "13.2.0-rc.4",
"@nrwl/next": "13.2.0-rc.4",
"@nrwl/node": "13.2.0-rc.4",
"@nrwl/nx-cloud": "13.0.0-beta.11",
"@nrwl/react": "13.2.0-rc.4",
"@nrwl/tao": "13.2.0-rc.4",
"@nrwl/web": "13.2.0-rc.4",
"@nrwl/workspace": "13.2.0-rc.4",
"@parcel/watcher": "2.0.0-alpha.11",
"@phenomnomnominal/tsquery": "4.1.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
@@ -84,11 +84,11 @@
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.4",
"@schematics/angular": "~13.0.0",
"@storybook/addon-essentials": "~6.3.0",
"@storybook/addon-essentials": "6.4.0-rc.3",
"@storybook/addon-knobs": "~6.3.0",
"@storybook/angular": "~6.3.0",
"@storybook/core": "~6.3.0",
"@storybook/react": "~6.3.0",
"@storybook/angular": "6.4.0-rc.3",
"@storybook/core": "6.4.0-rc.3",
"@storybook/react": "6.4.0-rc.3",
"@svgr/webpack": "5.5.0",
"@tailwindcss/typography": "^0.4.1",
"@testing-library/react": "11.2.6",
@@ -169,7 +169,7 @@
"jasmine-spec-reporter": "~4.2.1",
"jest": "27.2.3",
"jest-circus": "27.2.3",
"jest-preset-angular": "11.0.0-rc.3",
"jest-preset-angular": "11.0.0",
"jsonc-parser": "3.0.0",
"karma": "~4.0.0",
"karma-chrome-launcher": "~2.2.0",
@@ -298,4 +298,4 @@
"ng-packagr/rxjs": "6.6.7",
"**/xmlhttprequest-ssl": "~1.6.2"
}
}
}
+58 -1
View File
@@ -1052,7 +1052,64 @@
"alwaysAddToPackageJson": false
},
"jest-preset-angular": {
"version": "11.0.0-rc.3",
"version": "11.0.0",
"alwaysAddToPackageJson": false
},
"@storybook/manager-webpack5": {
"version": "6.4.0-rc.3",
"alwaysAddToPackageJson": false
},
"@storybook/builder-webpack5": {
"version": "6.4.0-rc.3",
"alwaysAddToPackageJson": false
},
"@storybook/angular": {
"version": "6.4.0-rc.3",
"alwaysAddToPackageJson": false
},
"@storybook/react": {
"version": "6.4.0-rc.3",
"alwaysAddToPackageJson": false
},
"@storybook/addon-essentials": {
"version": "6.4.0-rc.3",
"alwaysAddToPackageJson": false
},
"@ngrx/store": {
"version": "~13.0.0",
"alwaysAddToPackageJson": false
},
"@ngrx/effects": {
"version": "~13.0.0",
"alwaysAddToPackageJson": false
},
"@ngrx/entity": {
"version": "~13.0.0",
"alwaysAddToPackageJson": false
},
"@ngrx/router-store": {
"version": "~13.0.0",
"alwaysAddToPackageJson": false
},
"@ngrx/schematics": {
"version": "~13.0.0",
"alwaysAddToPackageJson": false
},
"@ngrx/store-devtools": {
"version": "~13.0.0",
"alwaysAddToPackageJson": false
},
"@ngrx/component-store": {
"version": "~13.0.0",
"alwaysAddToPackageJson": false
}
}
},
"13.2.1": {
"version": "13.2.1-beta.0",
"packages": {
"@angular/localize": {
"version": "^13.0.0",
"alwaysAddToPackageJson": false
}
}
+1
View File
@@ -23,6 +23,7 @@
"es2015": "esm2015/nrwl-angular.js",
"exports": {
"./generators": "./generators.js",
"./tailwind": "./tailwind.js",
"./src/generators/utils": "./src/generators/utils/index.js"
},
"author": "Victor Savkin",
@@ -0,0 +1,22 @@
import { InjectionToken, Provider } from 'injection-js';
import type { Transform } from 'ng-packagr/lib/graph/transform';
import { provideTransform } from 'ng-packagr/lib/graph/transform.di';
import { OPTIONS_TOKEN } from 'ng-packagr/lib/ng-package/options.di';
import {
STYLESHEET_PROCESSOR,
STYLESHEET_PROCESSOR_TOKEN,
} from 'ng-packagr/lib/styles/stylesheet-processor.di';
import { nxCompileNgcTransformFactory } from './compile-ngc.transform';
export const NX_COMPILE_NGC_TOKEN = new InjectionToken<Transform>(
`nx.v1.compileNgc`
);
export const NX_COMPILE_NGC_TRANSFORM = provideTransform({
provide: NX_COMPILE_NGC_TOKEN,
useFactory: nxCompileNgcTransformFactory,
deps: [STYLESHEET_PROCESSOR_TOKEN, OPTIONS_TOKEN],
});
export const NX_COMPILE_NGC_PROVIDERS: Provider[] = [
STYLESHEET_PROCESSOR,
NX_COMPILE_NGC_TRANSFORM,
];
@@ -5,27 +5,18 @@
* since these libraries will be compiled by the ngtsc.
*/
import { InjectionToken, Provider } from 'injection-js';
import type { Transform } from 'ng-packagr/lib/graph/transform';
import { transformFromPromise } from 'ng-packagr/lib/graph/transform';
import { provideTransform } from 'ng-packagr/lib/graph/transform.di';
import {
isEntryPoint,
isEntryPointInProgress,
} from 'ng-packagr/lib/ng-package/nodes';
import {
NgPackagrOptions,
OPTIONS_TOKEN,
} from 'ng-packagr/lib/ng-package/options.di';
import { compileSourceFiles } from './compile-source-files';
import { NgPackagrOptions } from 'ng-packagr/lib/ng-package/options.di';
import type { StylesheetProcessor as StylesheetProcessorClass } from 'ng-packagr/lib/styles/stylesheet-processor';
import {
STYLESHEET_PROCESSOR,
STYLESHEET_PROCESSOR_TOKEN,
} from 'ng-packagr/lib/styles/stylesheet-processor.di';
import { setDependenciesTsConfigPaths } from 'ng-packagr/lib/ts/tsconfig';
import * as path from 'path';
import * as ts from 'typescript';
import { compileSourceFiles } from '../../ngc/compile-source-files';
export const nxCompileNgcTransformFactory = (
StylesheetProcessor: typeof StylesheetProcessorClass,
@@ -75,16 +66,3 @@ export const nxCompileNgcTransformFactory = (
return graph;
});
};
export const NX_COMPILE_NGC_TOKEN = new InjectionToken<Transform>(
`nx.v1.compileNgc`
);
export const NX_COMPILE_NGC_TRANSFORM = provideTransform({
provide: NX_COMPILE_NGC_TOKEN,
useFactory: nxCompileNgcTransformFactory,
deps: [STYLESHEET_PROCESSOR_TOKEN, OPTIONS_TOKEN],
});
export const NX_COMPILE_NGC_PROVIDERS: Provider[] = [
STYLESHEET_PROCESSOR,
NX_COMPILE_NGC_TRANSFORM,
];
@@ -1,15 +1,22 @@
/**
* Wires everything together and provides it to the DI system, taking what
* we still want from the original ng-packagr library and replacing those
* where Nx takes over with Nx specific functions
* Adapted from the original ng-packagr source.
*
* Changes made:
* - Provide our own entryPointTransformFactory function.
* - Use NX_COMPILE_NGC_TOKEN instead of COMPILE_NGC_TOKEN.
* - Use NX_COMPILE_NGC_PROVIDERS instead of COMPILE_NGC_PROVIDERS.
* - Removed usage of WRITE_BUNDLES_TRANSFORM_TOKEN and WRITE_BUNDLES_TRANSFORM.
*/
import type { Provider } from 'injection-js';
import { InjectionToken } from 'injection-js';
import type { Transform } from 'ng-packagr/lib/graph/transform';
import { provideTransform } from 'ng-packagr/lib/graph/transform.di';
import { NX_COMPILE_NGC_PROVIDERS, NX_COMPILE_NGC_TOKEN } from './compile-ngc';
import { nxEntryPointTransformFactory } from './entry-point';
import {
NX_COMPILE_NGC_PROVIDERS,
NX_COMPILE_NGC_TOKEN,
} from './compile-ngc.di';
import { nxEntryPointTransformFactory } from './entry-point.transform';
import {
NX_WRITE_PACKAGE_TRANSFORM,
NX_WRITE_PACKAGE_TRANSFORM_TOKEN,
@@ -1,8 +1,8 @@
/**
* Adapted from original ng-packagr source
* Adapted from the original ng-packagr source.
*
* Remove writing bundles as they are not needed
* for incremental builds.
* Changes made:
* - Removed writing bundles as we don't generate them for incremental builds.
*/
import { logger } from '@nrwl/devkit';
@@ -26,8 +26,8 @@ import { pipe } from 'rxjs';
* - downlevelTs
* - relocateSourceMaps
* - writePackage
* - copyStagedFiles (esm, dts, sourcemaps)
* - writePackageJson
* - copyStagedFiles (esm, dts, sourcemaps)
* - writePackageJson
*
* The transformation pipeline is pluggable through the dependency injection system.
* Sub-transformations are passed to this factory function as arguments.
@@ -1,3 +1,10 @@
/**
* Adapted from the original ng-packagr source.
*
* Changes made:
* - Provide our own writePackageTransform function.
*/
import { InjectionToken } from 'injection-js';
import type { Transform } from 'ng-packagr/lib/graph/transform';
import {
@@ -5,7 +12,7 @@ import {
TransformProvider,
} from 'ng-packagr/lib/graph/transform.di';
import { OPTIONS_TOKEN } from 'ng-packagr/lib/ng-package/options.di';
import { nxWritePackageTransform } from './write-package';
import { nxWritePackageTransform } from './write-package.transform';
export const NX_WRITE_PACKAGE_TRANSFORM_TOKEN = new InjectionToken<Transform>(
`nx.v1.writePackageTransform`
@@ -1,8 +1,9 @@
/**
* Adapted from original ng-packagr
* Adapted from the original ng-packagr.
*
* Change the package.json metadata to only use
* the ESM2015 output as it's the only one generated.
* Changes made:
* - Change the package.json metadata to only use the ESM2020 output as it's the only one generated.
* - Remove package exports.
*/
import { logger } from '@nrwl/devkit';
@@ -18,13 +19,7 @@ import {
} from 'ng-packagr/lib/ng-package/nodes';
import { NgPackagrOptions } from 'ng-packagr/lib/ng-package/options.di';
import { NgPackage } from 'ng-packagr/lib/ng-package/package';
import {
copyFile,
exists,
rmdir,
stat,
writeFile,
} from 'ng-packagr/lib/utils/fs';
import { copyFile, rmdir, stat, writeFile } from 'ng-packagr/lib/utils/fs';
import { globFiles } from 'ng-packagr/lib/utils/glob';
import { ensureUnixPath } from 'ng-packagr/lib/utils/path';
import * as path from 'path';
@@ -110,7 +105,8 @@ export const nxWritePackageTransform = (options: NgPackagrOptions) =>
ngEntryPoint,
ngPackage,
{
module: relativeUnixFromDestPath(destinationFiles.fesm2015),
module: relativeUnixFromDestPath(destinationFiles.esm2020),
es2020: relativeUnixFromDestPath(destinationFiles.esm2020),
esm2020: relativeUnixFromDestPath(destinationFiles.esm2020),
typings: relativeUnixFromDestPath(destinationFiles.declarations),
// webpack v4+ specific flag to enable advanced optimizations and code splitting
@@ -1,8 +1,8 @@
/**
* Adapted from the original ng-packagr
* Adapted from the original ng-packagr.
*
* Wires everything together and provides it to the DI, but exchanges the parts
* we want to implement with Nx specific functions
* Changes made:
* - Use NX_ENTRY_POINT_TRANSFORM_TOKEN instead of ENTRY_POINT_TRANSFORM_TOKEN.
*/
import type { Provider } from 'injection-js';
@@ -23,7 +23,7 @@ import {
} from 'ng-packagr/lib/ng-package/options.di';
import { packageTransformFactory } from 'ng-packagr/lib/ng-package/package.transform';
import { PROJECT_TOKEN } from 'ng-packagr/lib/project.di';
import { NX_ENTRY_POINT_TRANSFORM_TOKEN } from './entry-point.di';
import { NX_ENTRY_POINT_TRANSFORM_TOKEN } from './entry-point/entry-point.di';
export const NX_PACKAGE_TRANSFORM_TOKEN = new InjectionToken<Transform>(
`nx.v1.packageTransform`
@@ -7,11 +7,11 @@ import * as buildableLibsUtils from '@nrwl/workspace/src/utilities/buildable-lib
import * as ngPackagr from 'ng-packagr';
import { BehaviorSubject } from 'rxjs';
import type { BuildAngularLibraryExecutorOptions } from '../package/schema';
import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/entry-point.di';
import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/ng-package/entry-point/entry-point.di';
import {
NX_PACKAGE_PROVIDERS,
NX_PACKAGE_TRANSFORM,
} from './ng-packagr-adjustments/package.di';
} from './ng-packagr-adjustments/ng-package/package.di';
import ngPackagrLiteExecutor from './ng-packagr-lite.impl';
describe('NgPackagrLite executor', () => {
@@ -7,11 +7,11 @@ import { NgPackagr } from 'ng-packagr';
import { resolve } from 'path';
import { createLibraryExecutor } from '../package/package.impl';
import type { BuildAngularLibraryExecutorOptions } from '../package/schema';
import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/entry-point.di';
import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/ng-package/entry-point/entry-point.di';
import {
NX_PACKAGE_PROVIDERS,
NX_PACKAGE_TRANSFORM,
} from './ng-packagr-adjustments/package.di';
} from './ng-packagr-adjustments/ng-package/package.di';
async function initializeNgPackgrLite(
options: BuildAngularLibraryExecutorOptions,
@@ -18,7 +18,6 @@ import {
import {
INIT_TS_CONFIG_TOKEN,
INIT_TS_CONFIG_TRANSFORM,
provideTsConfig,
} from 'ng-packagr/lib/ng-package/entry-point/init-tsconfig.di';
import {
DEFAULT_OPTIONS_PROVIDER,
@@ -3,6 +3,7 @@
*
* Changes made:
* - Added the filePath parameter to the cache key.
* - Refactored caching to take into account TailwindCSS processing.
* - Added PostCSS plugins needed to support TailwindCSS.
* - Added watch mode parameter.
*/
@@ -20,7 +21,12 @@ import * as log from 'ng-packagr/lib/utils/log';
import { dirname, extname, resolve } from 'path';
import * as postcssPresetEnv from 'postcss-preset-env';
import * as postcssUrl from 'postcss-url';
import { getTailwindPostCssPluginsIfPresent } from '../utilities/tailwindcss';
import {
getTailwindPostCssPlugins,
getTailwindSetup,
tailwindDirectives,
TailwindSetup,
} from '../utilities/tailwindcss';
const postcss = require('postcss');
@@ -47,6 +53,7 @@ export class StylesheetProcessor {
private targets: string[];
private postCssProcessor: ReturnType<typeof postcss>;
private esbuild = new EsbuildExecutor();
private tailwindSetup: TailwindSetup | undefined;
constructor(
private readonly basePath: string,
@@ -71,6 +78,7 @@ export class StylesheetProcessor {
this.browserslistData = browserslist(undefined, { path: this.basePath });
this.targets = transformSupportedBrowsersToTargets(this.browserslistData);
this.tailwindSetup = getTailwindSetup(this.basePath);
this.postCssProcessor = this.createPostCssPlugins();
}
@@ -84,11 +92,12 @@ export class StylesheetProcessor {
let key: string | undefined;
if (
this.cacheDirectory &&
!content.includes('@import') &&
!content.includes('@use') &&
this.cacheDirectory
!this.containsTailwindDirectives(content)
) {
// No transitive deps, we can cache more aggressively.
// No transitive deps and no Tailwind directives, we can cache more aggressively.
key = await generateKey(content, ...this.browserslistData, filePath);
const result = await readCacheEntry(this.cacheDirectory, key);
if (result) {
@@ -101,18 +110,23 @@ export class StylesheetProcessor {
// Render pre-processor language (sass, styl, less)
const renderedCss = await this.renderCss(filePath, content);
// We cannot cache CSS re-rendering phase, because a transitive dependency via (@import) can case different CSS output.
// Example a change in a mixin or SCSS variable.
if (!key) {
key = await generateKey(renderedCss, ...this.browserslistData, filePath);
}
let containsTailwindDirectives = false;
if (this.cacheDirectory) {
const cachedResult = await readCacheEntry(this.cacheDirectory, key);
if (cachedResult) {
cachedResult.warnings.forEach((msg) => log.warn(msg));
containsTailwindDirectives = this.containsTailwindDirectives(renderedCss);
if (!containsTailwindDirectives) {
// No Tailwind directives to process by PostCSS, we can return cached results
if (!key) {
key = await generateKey(
renderedCss,
...this.browserslistData,
filePath
);
}
return cachedResult.css;
const cachedResult = await this.getCachedResult(key);
if (cachedResult) {
return cachedResult;
}
}
}
@@ -122,6 +136,17 @@ export class StylesheetProcessor {
to: filePath.replace(extname(filePath), '.css'),
});
if (this.cacheDirectory && containsTailwindDirectives) {
// We had Tailwind directives to process by PostCSS, only now
// is safe to return cached results
key = await generateKey(result.css, ...this.browserslistData, filePath);
const cachedResult = await this.getCachedResult(key);
if (cachedResult) {
return cachedResult;
}
}
const warnings = result.warnings().map((w) => w.toString());
const { code, warnings: esBuildWarnings } = await this.esbuild.transform(
result.css,
@@ -156,19 +181,41 @@ export class StylesheetProcessor {
return code;
}
private async getCachedResult(key: string): Promise<string | undefined> {
const cachedResult = await readCacheEntry(
this.cacheDirectory as string,
key
);
if (cachedResult) {
cachedResult.warnings.forEach((msg) => log.warn(msg));
return cachedResult.css;
}
return undefined;
}
private containsTailwindDirectives(content: string): boolean {
return (
this.tailwindSetup && tailwindDirectives.some((d) => content.includes(d))
);
}
private createPostCssPlugins(): ReturnType<typeof postcss> {
const postCssPlugins = [];
if (this.cssUrl !== CssUrl.none) {
postCssPlugins.push(postcssUrl({ url: this.cssUrl }));
}
postCssPlugins.push(
...getTailwindPostCssPluginsIfPresent(
this.basePath,
this.styleIncludePaths,
this.watch
)
);
if (this.tailwindSetup) {
postCssPlugins.push(
...getTailwindPostCssPlugins(
this.tailwindSetup,
this.styleIncludePaths,
this.watch
)
);
}
postCssPlugins.push(
postcssPresetEnv({
@@ -288,7 +335,7 @@ function customSassImporter(
return undefined;
}
const result = resolveImport(url.substr(1), prev);
const result = resolveImport(url.substring(1), prev);
if (!result) {
return undefined;
}
@@ -4,11 +4,21 @@ import { existsSync } from 'fs';
import { join, relative } from 'path';
import * as postcssImport from 'postcss-import';
export function getTailwindPostCssPluginsIfPresent(
basePath: string,
includePaths?: string[],
watch?: boolean
) {
export interface TailwindSetup {
tailwindConfigPath: string;
tailwindPackagePath: string;
}
export const tailwindDirectives = [
'@tailwind',
'@apply',
'@layer',
'@variants',
'@responsive',
'@screen',
];
export function getTailwindSetup(basePath: string): TailwindSetup | undefined {
// Try to find TailwindCSS configuration file in the project or workspace root.
const tailwindConfigFile = 'tailwind.config.js';
let tailwindConfigPath: string | undefined;
@@ -22,7 +32,7 @@ export function getTailwindPostCssPluginsIfPresent(
// Only load Tailwind CSS plugin if configuration file was found.
if (!tailwindConfigPath) {
return [];
return undefined;
}
let tailwindPackagePath: string | undefined;
@@ -39,13 +49,21 @@ export function getTailwindPostCssPluginsIfPresent(
` To enable Tailwind CSS, please install the 'tailwindcss' package.`
);
return [];
return undefined;
}
if (!tailwindPackagePath) {
return [];
return undefined;
}
return { tailwindConfigPath, tailwindPackagePath };
}
export function getTailwindPostCssPlugins(
{ tailwindConfigPath, tailwindPackagePath }: TailwindSetup,
includePaths?: string[],
watch?: boolean
) {
if (process.env['TAILWIND_MODE'] === undefined) {
process.env['TAILWIND_MODE'] = watch ? 'watch' : 'build';
}
@@ -53,7 +71,7 @@ export function getTailwindPostCssPluginsIfPresent(
return [
postcssImport({
addModulesDirectories: includePaths ?? [],
resolve: (url: string) => (url.startsWith('~') ? url.substr(1) : url),
resolve: (url: string) => (url.startsWith('~') ? url.substring(1) : url),
}),
require(tailwindPackagePath)({ config: tailwindConfigPath }),
];
@@ -41,6 +41,9 @@ export class TestButtonComponent {
@Input() style: ButtonStyle = 'default';
@Input() age?: number;
@Input() isOn = false;
@Input() message: string | undefined;
@Input() anotherProp: any;
@Input() anotherNeverProp: never;
}`
);
});
@@ -31,7 +31,7 @@ export function componentStoryGenerator(
generateFiles(tree, templatesDir, destinationDir, {
componentFileName: componentFileName,
componentName: componentName,
props,
props: props.filter((p) => typeof p.defaultValue !== 'undefined'),
tmpl: '',
});
}
@@ -5,5 +5,5 @@
"types": ["jasmine", "node"]
},
"files": ["src/test.ts"],
"include": ["**/*.spec.ts", "**/*.d.ts"]
"include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"]
}
@@ -98,7 +98,7 @@ describe('karmaProject', () => {
types: ['jasmine', 'node'],
},
files: ['src/test.ts'],
include: ['**/*.spec.ts', '**/*.d.ts'],
include: ['**/*.spec.ts', '**/*.test.ts', '**/*.d.ts'],
});
});
@@ -140,7 +140,7 @@ describe('karmaProject', () => {
types: ['jasmine', 'node'],
},
files: ['src/test.ts', 'src/polyfills.ts'],
include: ['**/*.spec.ts', '**/*.d.ts'],
include: ['**/*.spec.ts', '**/*.test.ts', '**/*.d.ts'],
});
});
@@ -0,0 +1,5 @@
{
"lib": {
"entryFile": "src/index.ts"
}
}
@@ -1,7 +0,0 @@
{
"ngPackage": {
"lib": {
"entryFile": "src/index.ts"
}
}
}
@@ -47,7 +47,7 @@ describe('librarySecondaryEntryPoint generator', () => {
'libs/lib1/package.json',
JSON.stringify({ name: '@my-org/lib1' })
);
tree.write('libs/lib1/testing/package.json', '');
tree.write('libs/lib1/testing/ng-package.json', '');
await expect(() =>
librarySecondaryEntryPointGenerator(tree, {
@@ -72,7 +72,7 @@ describe('librarySecondaryEntryPoint generator', () => {
library: 'lib1',
});
expect(tree.exists('libs/lib1/testing/package.json')).toBeTruthy();
expect(tree.exists('libs/lib1/testing/ng-package.json')).toBeTruthy();
expect(tree.exists('libs/lib1/testing/README.md')).toBeTruthy();
expect(tree.exists('libs/lib1/testing/src/index.ts')).toBeTruthy();
expect(
@@ -98,8 +98,8 @@ describe('librarySecondaryEntryPoint generator', () => {
library: 'lib1',
});
const packageJson = readJson(tree, 'libs/lib1/testing/package.json');
expect(packageJson.ngPackage.lib.entryFile).toBe('src/index.ts');
const ngPackageJson = readJson(tree, 'libs/lib1/testing/ng-package.json');
expect(ngPackageJson.lib.entryFile).toBe('src/index.ts');
});
it('should add the path mapping for the entry point', async () => {
@@ -197,7 +197,7 @@ describe('librarySecondaryEntryPoint generator', () => {
expect(
tree.exists('libs/lib1/testing/src/lib/testing.module.ts')
).toBeFalsy();
expect(tree.exists('libs/lib1/testing/package.json')).toBeTruthy();
expect(tree.exists('libs/lib1/testing/ng-package.json')).toBeTruthy();
expect(tree.exists('libs/lib1/testing/README.md')).toBeTruthy();
expect(tree.exists('libs/lib1/testing/src/index.ts')).toBeTruthy();
expect(
@@ -8,7 +8,9 @@ export function assertCompatibleStorybookVersion() {
)).version;
} catch {}
if (storybookVersion && lt(storybookVersion, '6.2.0')) {
throw new Error('Incompatible Storybook Version');
if (storybookVersion && lt(storybookVersion, '6.4.0-rc.1')) {
throw new Error(
'Incompatible Storybook Version: Please use a version of @storybook/angular higher than 6.4.0-rc.1'
);
}
}
@@ -33,7 +33,7 @@ describe('StorybookConfiguration generator', () => {
});
jest.resetModules();
jest.doMock('@storybook/angular/package.json', () => ({
version: '6.2.0',
version: '6.4.0-rc.1',
}));
jest.spyOn(fileUtils, 'readPackageJson').mockReturnValue({
devDependencies: {
@@ -43,7 +43,7 @@ describe('StorybookConfiguration generator', () => {
});
});
it('should throw when the @storybook/angular version is lower than 6.2.0', async () => {
it('should throw when the @storybook/angular version is lower than 6.4.0-rc.1', async () => {
jest.doMock('@storybook/angular/package.json', () => ({
version: '5.1.0',
}));
@@ -52,7 +52,9 @@ describe('StorybookConfiguration generator', () => {
storybookConfigurationGenerator(tree, <StorybookConfigurationOptions>{
name: libName,
})
).rejects.toThrow('Incompatible Storybook Version');
).rejects.toThrowErrorMatchingInlineSnapshot(
'"Incompatible Storybook Version: Please use a version of @storybook/angular higher than 6.4.0-rc.1"'
);
});
it('should throw when generateCypressSpecs is true and generateStories is false', async () => {
@@ -1,4 +1,6 @@
import type { GeneratorCallback, Tree } from '@nrwl/devkit';
import { addDependenciesToPackageJson } from '@nrwl/devkit';
import { storybookVersion } from '../../utils/versions';
import { assertCompatibleStorybookVersion } from './lib/assert-compatible-storybook-version';
import { generateStories } from './lib/generate-stories';
import { generateStorybookConfiguration } from './lib/generate-storybook-configuration';
@@ -11,13 +13,31 @@ export async function storybookConfigurationGenerator(
): Promise<GeneratorCallback> {
assertCompatibleStorybookVersion();
validateOptions(options);
const installTask = await generateStorybookConfiguration(tree, options);
// TODO(coly010/juristr): remove when @nrwl/storybook has been updated
const angularStorybookInstallTask = addDependenciesToPackageJson(
tree,
{},
{
'@storybook/angular': storybookVersion,
'@storybook/manager-webpack5': storybookVersion,
'@storybook/builder-webpack5': storybookVersion,
'@storybook/addon-essentials': storybookVersion,
}
);
const storybookGeneratorInstallTask = await generateStorybookConfiguration(
tree,
options
);
if (options.generateStories) {
generateStories(tree, options);
}
return installTask;
return () => {
angularStorybookInstallTask();
storybookGeneratorInstallTask();
};
}
export default storybookConfigurationGenerator;
@@ -49,6 +49,15 @@ describe('update-angular-jest-config migration', () => {
const updatedJestFile = tree.read('apps/testing/jest.config.js', 'utf-8');
expect(updatedJestFile).toMatchSnapshot();
});
it("shouldn't error on null targets", async () => {
const tree = createTreeWithEmptyWorkspace(2);
addProjectConfiguration(tree, 'app', {
root: 'apps/testing',
});
const promise = updateAngularJestConfig(tree);
await expect(promise).resolves.not.toThrow();
});
});
describe('ast transformations', () => {
@@ -246,4 +255,49 @@ transform: {
"
`);
});
it('should not add multiple transform ignore patterns', () => {
// ARRANGE
const jestConfig = `module.exports = {
displayName: 'app1',
preset: '../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
},
coverageDirectory: '../../coverage/apps/app1',
transform: {
'^.+\\.(json)$': 'json_transformer',
'^.+\\.(ts|js|html)$': 'jest-preset-angular',
},
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
};`;
// ACT
const updatedFile = replaceTransformAndAddIgnorePattern(jestConfig);
// ASSERT
expect(updatedFile).toMatchInlineSnapshot(`
"module.exports = {
displayName: 'app1',
preset: '../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\\\.(html|svg)$',
},
},
coverageDirectory: '../../coverage/apps/app1',
transform: {
'^.+\\\\.(json)$': 'json_transformer',
'^.+\\\\.(ts|mjs|js|html)$': 'jest-preset-angular',
},
transformIgnorePatterns: ['node_modules/(?!.*\\\\.mjs$)'],
};"
`);
});
});
@@ -11,8 +11,8 @@ export default async function (tree: Tree) {
for (const [projectName, project] of projects.entries()) {
if (
project.targets.test &&
project.targets.test.executor === '@nrwl/jest:jest'
project.targets?.test &&
project.targets?.test.executor === '@nrwl/jest:jest'
) {
const jestConfigPath =
project.targets.test.options && project.targets.test.options.jestConfig;
@@ -85,6 +85,14 @@ function updateTransformIgnorePattern(fileContents: string) {
let TRANSFORM_IGNORE_PATTERN_STRING =
"transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],";
if (
fileContents.includes(
"transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)']"
)
) {
return fileContents;
}
const ast = tsquery.ast(fileContents);
const transformObjectNode = tsquery(ast, TRANSFORM_OBJECT_AST_QUERY, {
@@ -11,6 +11,7 @@ describe('update-libraries migration', () => {
targets: {
build: {
executor: '@nrwl/angular:ng-packagr-lite',
options: {},
},
},
});
@@ -47,6 +48,7 @@ describe('update-libraries migration', () => {
targets: {
build: {
executor: '@nrwl/angular:ng-packagr-lite',
options: {},
},
},
});
@@ -74,4 +76,13 @@ describe('update-libraries migration', () => {
expect(tsconfigFile.includes('amdId')).toBeFalsy();
expect(tsconfigFile.includes('umdId')).toBeFalsy();
});
it("shouldn't error on null targets", async () => {
const tree = createTreeWithEmptyWorkspace(2);
addProjectConfiguration(tree, 'app', {
root: 'apps/testing',
});
const promise = updateLibraries(tree);
await expect(promise).resolves.not.toThrow();
});
});
@@ -1,5 +1,6 @@
import type { Tree } from '@nrwl/devkit';
import { getProjects, joinPathFragments, updateJson } from '@nrwl/devkit';
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
export default async function (tree: Tree) {
const LIBRARY_EXECUTORS = [
@@ -10,28 +11,27 @@ export default async function (tree: Tree) {
const tsConfigFilesToUpdate = new Set<string>();
const ngPackageFilesToUpdate = new Set<string>();
for (const [projectName, project] of projects.entries()) {
for (const [targetName, target] of Object.entries(project.targets)) {
if (LIBRARY_EXECUTORS.includes(target.executor)) {
// UPDATE THE TSCONFIG JSON
const tsConfigPath = joinPathFragments(
project.root,
'tsconfig.lib.prod.json'
);
if (tree.exists(tsConfigPath)) {
tsConfigFilesToUpdate.add(tsConfigPath);
}
const ngPackageFilePath = joinPathFragments(
project.root,
'ng-package.json'
);
if (tree.exists(ngPackageFilePath)) {
ngPackageFilesToUpdate.add(ngPackageFilePath);
}
LIBRARY_EXECUTORS.forEach((executor) => {
forEachExecutorOptions(tree, executor, (opts, projectName) => {
const project = projects.get(projectName);
// UPDATE THE TSCONFIG JSON
const tsConfigPath = joinPathFragments(
project.root,
'tsconfig.lib.prod.json'
);
if (tree.exists(tsConfigPath)) {
tsConfigFilesToUpdate.add(tsConfigPath);
}
}
}
const ngPackageFilePath = joinPathFragments(
project.root,
'ng-package.json'
);
if (tree.exists(ngPackageFilePath)) {
ngPackageFilesToUpdate.add(ngPackageFilePath);
}
});
});
for (const tsConfigPath of tsConfigFilesToUpdate) {
updateJson(tree, tsConfigPath, (json) => {
+3 -2
View File
@@ -2,7 +2,8 @@ export const nxVersion = '*';
export const angularVersion = '^13.0.0';
export const angularDevkitVersion = '~13.0.0';
export const angularJsVersion = '1.7.9';
export const ngrxVersion = '~12.5.0';
export const ngrxVersion = '~13.0.0';
export const rxjsVersion = '~7.4.0';
export const jestPresetAngularVersion = '11.0.0-rc.3';
export const jestPresetAngularVersion = '11.0.0';
export const angularEslintVersion = '~12.6.0';
export const storybookVersion = '~6.4.0-rc.3';
+1 -1
View File
@@ -6,6 +6,6 @@
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts", "**/*_test.ts"],
"include": ["**/*.ts"]
}
+1
View File
@@ -9,6 +9,7 @@
"**/*.spec.ts",
"**/*.test.ts",
"**/*_spec.ts",
"**/*_test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
+1 -1
View File
@@ -6,6 +6,6 @@
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts", "**/*_test.ts"],
"include": ["**/*.ts"]
}
+1
View File
@@ -9,6 +9,7 @@
"**/*.spec.ts",
"**/*.test.ts",
"**/*_spec.ts",
"**/*_test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
+1 -1
View File
@@ -6,6 +6,6 @@
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts", "**/*_test.ts"],
"include": ["**/*.ts"]
}
@@ -9,6 +9,7 @@
"**/*.spec.ts",
"**/*.test.ts",
"**/*_spec.ts",
"**/*_test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
@@ -6,6 +6,6 @@
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts", "**/*_test.ts"],
"include": ["**/*.ts"]
}
@@ -9,6 +9,7 @@
"**/*.spec.ts",
"**/*.test.ts",
"**/*_spec.ts",
"**/*_test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
@@ -35,19 +35,22 @@ describe('visitNotIgnoredFiles', () => {
expect(visitor).not.toHaveBeenCalledWith('dir/node_modules/file1.ts');
});
it('should be able to visit the root', () => {
tree.write('.gitignore', 'node_modules');
it.each(['', '.', '/', './'])(
'should be able to visit the root path "%s"',
(dirPath) => {
tree.write('.gitignore', 'node_modules');
tree.write('dir/file1.ts', '');
tree.write('dir/node_modules/file1.ts', '');
tree.write('dir/dir2/file2.ts', '');
tree.write('dir/file1.ts', '');
tree.write('dir/node_modules/file1.ts', '');
tree.write('dir/dir2/file2.ts', '');
const visitor = jest.fn();
visitNotIgnoredFiles(tree, '', visitor);
const visitor = jest.fn();
visitNotIgnoredFiles(tree, dirPath, visitor);
expect(visitor).toHaveBeenCalledWith('.gitignore');
expect(visitor).toHaveBeenCalledWith('dir/file1.ts');
expect(visitor).toHaveBeenCalledWith('dir/dir2/file2.ts');
expect(visitor).not.toHaveBeenCalledWith('dir/node_modules/file1.ts');
});
expect(visitor).toHaveBeenCalledWith('.gitignore');
expect(visitor).toHaveBeenCalledWith('dir/file1.ts');
expect(visitor).toHaveBeenCalledWith('dir/dir2/file2.ts');
expect(visitor).not.toHaveBeenCalledWith('dir/node_modules/file1.ts');
}
);
});
@@ -1,6 +1,6 @@
import type { Tree } from '@nrwl/tao/src/shared/tree';
import { join } from 'path';
import ignore, { Ignore } from 'ignore';
import { join, relative, sep } from 'path';
/**
* Utility to act on all files in a tree that are not ignored by git.
@@ -15,6 +15,7 @@ export function visitNotIgnoredFiles(
ig = ignore();
ig.add(tree.read('.gitignore', 'utf-8'));
}
dirPath = normalizePathRelativeToRoot(dirPath, tree.root);
if (dirPath !== '' && ig?.ignores(dirPath)) {
return;
}
@@ -30,3 +31,7 @@ export function visitNotIgnoredFiles(
}
}
}
function normalizePathRelativeToRoot(path: string, root: string): string {
return relative(root, join(root, path)).split(sep).join('/');
}
+1 -1
View File
@@ -6,6 +6,6 @@
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts", "**/*_test.ts"],
"include": ["**/*.ts"]
}
+1
View File
@@ -9,6 +9,7 @@
"**/*.spec.ts",
"**/*.test.ts",
"**/*_spec.ts",
"**/*_test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
+1 -1
View File
@@ -6,6 +6,6 @@
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts", "**/*_test.ts"],
"include": ["**/*.ts"]
}
@@ -9,6 +9,7 @@
"**/*.spec.ts",
"**/*.test.ts",
"**/*_spec.ts",
"**/*_test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
+1 -1
View File
@@ -6,6 +6,6 @@
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts", "**/*_test.ts"],
"include": ["**/*.ts"]
}
+1
View File
@@ -9,6 +9,7 @@
"**/*.spec.ts",
"**/*.test.ts",
"**/*_spec.ts",
"**/*_test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
+1 -1
View File
@@ -6,6 +6,6 @@
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts", "**/*_test.ts"],
"include": ["**/*.ts"]
}
+1
View File
@@ -9,6 +9,7 @@
"**/*.spec.ts",
"**/*.test.ts",
"**/*_spec.ts",
"**/*_test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
+1
View File
@@ -36,6 +36,7 @@
"@nrwl/devkit": "*",
"identity-obj-proxy": "3.0.0",
"jest-resolve": "27.2.2",
"resolve.exports": "1.1.0",
"rxjs": "^6.5.4",
"tslib": "^2.3.0",
"@jest/reporters": "27.2.2",
+8
View File
@@ -1,4 +1,5 @@
import { dirname, extname } from 'path';
import { resolve as resolveExports } from 'resolve.exports';
import type defaultResolver from 'jest-resolve/build/defaultResolver';
interface ResolveOptions {
@@ -60,6 +61,13 @@ module.exports = function (path: string, options: ResolveOptions) {
...pkg,
main: pkg.main || pkg.es2015 || pkg.module,
}),
pathFilter: (pkg) => {
if (!pkg.exports) {
return path;
}
return resolveExports(pkg, path) || path;
},
});
}
} catch (e) {
+1 -1
View File
@@ -1,7 +1,7 @@
export = {
testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
resolver: '@nrwl/jest/plugins/resolver',
moduleFileExtensions: ['ts', 'js', 'html'],
moduleFileExtensions: ['ts', 'js', 'mjs', 'html'],
coverageReporters: ['html'],
transform: {
'^.+\\.(ts|js|html)$': 'ts-jest',
+1 -1
View File
@@ -6,6 +6,6 @@
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts", "**/*_test.ts"],
"include": ["**/*.ts"]
}
+1
View File
@@ -9,6 +9,7 @@
"**/*.spec.ts",
"**/*.test.ts",
"**/*_spec.ts",
"**/*_test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
+1 -1
View File
@@ -6,6 +6,6 @@
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts"],
"exclude": ["**/*.spec.ts", "**/*.test.ts", "**/*_spec.ts", "**/*_test.ts"],
"include": ["**/*.ts"]
}
+1
View File
@@ -9,6 +9,7 @@
"**/*.spec.ts",
"**/*.test.ts",
"**/*_spec.ts",
"**/*_test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",

Some files were not shown because too many files have changed in this diff Show More