refactor: use yarn workspaces (#420)
@@ -1,4 +1,4 @@
|
||||
FROM node:16.12.0-buster
|
||||
FROM node:17.9.0-buster
|
||||
|
||||
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
@@ -27,4 +27,5 @@ RUN set -eux; \
|
||||
rustup update; \
|
||||
rustup target add wasm32-unknown-unknown; \
|
||||
cargo install cargo-insta; \
|
||||
rustup component add clippy;
|
||||
rustup component add clippy; \
|
||||
corepack enable
|
||||
|
||||
@@ -16,7 +16,7 @@ integration/todo/output
|
||||
integration/*.js
|
||||
integration/*.cjs
|
||||
integration/*.map
|
||||
src/napi/package-*
|
||||
packages/qwik/src/napi/package-*
|
||||
target
|
||||
*.node
|
||||
todo-express/
|
||||
|
||||
4
.github/workflows/bench.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
optimizer: ${{ steps.filter.outputs.optimizer }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
if: ${{ needs.changes.outputs.optimizer == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Cache
|
||||
uses: actions/cache@v1
|
||||
|
||||
270
.github/workflows/ci.yml
vendored
@@ -6,8 +6,6 @@ on:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
name: 'Release'
|
||||
description: 'Publish to NPM, and create a Github release.'
|
||||
inputs:
|
||||
disttag:
|
||||
description: 'Publish to NPM using this dist-tag, push the git-tag to the repo and create a Github release. A "latest" and "next" dist-tags will use the version number already committed in package.json.'
|
||||
@@ -35,21 +33,21 @@ jobs:
|
||||
run: echo ${{ github.head_ref }}
|
||||
- name: NPM Dist Tag
|
||||
run: echo "${{ github.event.inputs.disttag }}"
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
fullbuild:
|
||||
- 'src/**/*.ts'
|
||||
- 'src/**/*.tsx'
|
||||
- 'src/**/*.js'
|
||||
- 'src/**/*.mjs'
|
||||
- 'src/**/*.cjs'
|
||||
- 'src/**/*.jsx'
|
||||
- 'src/**/*.toml'
|
||||
- 'src/**/*.rs'
|
||||
- 'src/**/*.lock'
|
||||
- 'packages/qwik/src/**/*.ts'
|
||||
- 'packages/qwik/src/**/*.tsx'
|
||||
- 'packages/qwik/src/**/*.js'
|
||||
- 'packages/qwik/src/**/*.mjs'
|
||||
- 'packages/qwik/src/**/*.cjs'
|
||||
- 'packages/qwik/src/**/*.jsx'
|
||||
- 'packages/qwik/src/**/*.toml'
|
||||
- 'packages/qwik/src/**/*.rs'
|
||||
- 'packages/qwik/src/**/*.lock'
|
||||
- 'yarn.lock'
|
||||
- 'tsconfig.json'
|
||||
- name: Print fullbuild output
|
||||
@@ -60,61 +58,58 @@ jobs:
|
||||
name: Build Package
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: 'yarn'
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Cache NPM Dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: npm-cache-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
|
||||
- run: corepack enable
|
||||
|
||||
- name: Install NPM Dependencies
|
||||
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
|
||||
run: yarn install --immutable --network-timeout 300000
|
||||
|
||||
- name: Build Package
|
||||
run: node scripts --tsc --build --api --set-dist-tag="${{ github.event.inputs.disttag }}"
|
||||
run: yarn node scripts --tsc --build --api --set-dist-tag="${{ github.event.inputs.disttag }}"
|
||||
|
||||
- name: Print Package Dist Build
|
||||
run: tree dist-dev/@builder.io-qwik/
|
||||
run: tree packages/qwik/dist/
|
||||
|
||||
- name: Upload Package Build Artifacts
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: dist-dev-builder-io-qwik
|
||||
path: dist-dev/@builder.io-qwik/
|
||||
path: packages/qwik/dist/
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Build Create Qwik CLI
|
||||
run: node scripts --cli
|
||||
run: yarn node scripts --cli
|
||||
|
||||
- name: Print Create Qwik CLI Dist Build
|
||||
run: tree dist-dev/create-qwik/
|
||||
run: tree packages/create-qwik/dist/
|
||||
|
||||
- name: Upload Create Qwik CLI Build Artifacts
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: dist-dev-create-qwik
|
||||
path: dist-dev/create-qwik/
|
||||
path: packages/create-qwik/dist/
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Build Eslint rules
|
||||
run: node scripts --eslint
|
||||
run: yarn node scripts --eslint
|
||||
|
||||
- name: Print Eslint rules Dist Build
|
||||
run: tree dist-dev/eslint-plugin-qwik/
|
||||
run: tree packages/eslint-plugin-qwik/dist/
|
||||
|
||||
- name: Upload Eslint rules Build Artifacts
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: dist-dev-eslint-plugin-qwik
|
||||
path: dist-dev/eslint-plugin-qwik/
|
||||
path: packages/eslint-plugin-qwik/dist/
|
||||
if-no-files-found: error
|
||||
|
||||
############ BUILD WASM ############
|
||||
@@ -128,13 +123,21 @@ jobs:
|
||||
- name: Print fullbuild output
|
||||
run: echo ${{ needs.changes.outputs.fullbuild }}
|
||||
|
||||
- name: Checkout
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: 'yarn'
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: corepack enable
|
||||
|
||||
- name: Install Rust toolchain
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -144,17 +147,6 @@ jobs:
|
||||
toolchain: 1.59.0
|
||||
target: wasm32-unknown-unknown
|
||||
|
||||
- name: Checkout
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Cache NPM Dependencies
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: npm-cache-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
|
||||
|
||||
- name: Cache cargo dependencies
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/cache@v2
|
||||
@@ -167,27 +159,27 @@ jobs:
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: src/wasm/target
|
||||
key: cargo-build-wasm-${{ runner.os }}-${{ hashFiles('./src/wasm/Cargo.lock') }}
|
||||
path: packages/qwik/src/wasm/target
|
||||
key: cargo-build-wasm-${{ runner.os }}-${{ hashFiles('./packages/qwik/src/wasm/Cargo.lock') }}
|
||||
|
||||
- name: Install NPM Dependencies
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
|
||||
run: yarn install --immutable --network-timeout 300000
|
||||
|
||||
- name: Build WASM
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: node scripts --wasm --set-dist-tag="${{ github.event.inputs.disttag }}"
|
||||
run: yarn node scripts --wasm --set-dist-tag="${{ github.event.inputs.disttag }}"
|
||||
|
||||
- name: Print WASM Dist Build
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: tree dist-dev/@builder.io-qwik/bindings/
|
||||
run: tree packages/qwik/dist/bindings/
|
||||
|
||||
- name: Upload WASM Build Artifacts
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: dist-bindings-wasm
|
||||
path: dist-dev/@builder.io-qwik/bindings/*
|
||||
path: packages/qwik/dist/bindings/*
|
||||
if-no-files-found: error
|
||||
|
||||
############ BUILD PLATFORM BINDINGS ############
|
||||
@@ -197,40 +189,41 @@ jobs:
|
||||
settings:
|
||||
- host: macos-latest
|
||||
target: x86_64-apple-darwin
|
||||
build: yarn build.platform
|
||||
build: yarn node scripts --platform-binding
|
||||
|
||||
- host: macos-latest
|
||||
target: aarch64-apple-darwin
|
||||
build: |
|
||||
export SDKROOT=$(xcrun -sdk macosx11.1 --show-sdk-path)
|
||||
export MACOSX_DEPLOYMENT_TARGET=$(xcrun -sdk macosx11.1 --show-sdk-platform-version)
|
||||
yarn build.platform --platform-target=aarch64-apple-darwin
|
||||
yarn node scripts --platform-binding --platform-target=aarch64-apple-darwin
|
||||
|
||||
- host: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
build: yarn build.platform
|
||||
build: yarn node scripts --platform-binding
|
||||
|
||||
name: Build ${{ matrix.settings.target }}
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
|
||||
needs: changes
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./src/napi/
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: 'yarn'
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: corepack enable
|
||||
shell: bash
|
||||
|
||||
- name: Install Rust toolchain
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -240,13 +233,6 @@ jobs:
|
||||
toolchain: 1.59.0
|
||||
target: ${{ matrix.settings.target }}
|
||||
|
||||
- name: Cache NPM Dependencies
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: npm-cache-${{ matrix.settings.target }}-${{ hashFiles('yarn.lock') }}
|
||||
|
||||
- name: Pull Latest Image
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' && matrix.settings.docker }}
|
||||
run: ${{ matrix.settings.docker }}
|
||||
@@ -277,7 +263,7 @@ jobs:
|
||||
|
||||
- name: Install NPM Dependencies
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
|
||||
run: yarn install --immutable --network-timeout 300000
|
||||
|
||||
- name: Build Platform Binding
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
@@ -289,7 +275,7 @@ jobs:
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: dist-bindings-${{ matrix.settings.target }}
|
||||
path: dist-dev/@builder.io-qwik/bindings/*.node
|
||||
path: packages/qwik/dist/bindings/*.node
|
||||
if-no-files-found: error
|
||||
|
||||
############ BUILD DISTRIBUTION ############
|
||||
@@ -306,19 +292,10 @@ jobs:
|
||||
- changes
|
||||
|
||||
steps:
|
||||
- name: Setup Node
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 16.x
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- name: Create dist-dev/@builder.io-qwik directory
|
||||
- name: Create packages/qwik/dist/ directory
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: |
|
||||
mkdir dist-dev/
|
||||
mkdir dist-dev/@builder.io-qwik/
|
||||
mkdir dist-dev/@builder.io-qwik/bindings/
|
||||
mkdir -p packages/qwik/dist/bindings/
|
||||
|
||||
- name: Download Build Artifacts
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
@@ -330,7 +307,7 @@ jobs:
|
||||
|
||||
- name: Move Distribution Artifacts
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: mv dist-dev-builder-io-qwik/* dist-dev/@builder.io-qwik/
|
||||
run: mv dist-dev-builder-io-qwik/* packages/qwik/dist/
|
||||
|
||||
- name: Print Bindings Artifacts
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
@@ -338,18 +315,18 @@ jobs:
|
||||
|
||||
- name: Move Binding Artifacts
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: mv dist-bindings-*/* dist-dev/@builder.io-qwik/bindings/
|
||||
run: mv dist-bindings-*/* packages/qwik/dist/bindings/
|
||||
|
||||
- name: Print dist-dev
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: tree dist-dev/
|
||||
run: tree packages/qwik/dist/
|
||||
|
||||
- name: Upload Qwik Distribution Artifact
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: builderio-qwik-distribution
|
||||
path: dist-dev/@builder.io-qwik/*
|
||||
path: packages/qwik/dist/*
|
||||
if-no-files-found: error
|
||||
|
||||
############ RELEASE ############
|
||||
@@ -364,14 +341,17 @@ jobs:
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: 'yarn'
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- run: corepack enable
|
||||
|
||||
- name: Download Build Artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
@@ -384,33 +364,26 @@ jobs:
|
||||
|
||||
- name: Move Distribution Artifacts
|
||||
run: |
|
||||
mkdir dist-dev/
|
||||
mkdir dist-dev/@builder.io-qwik/
|
||||
mv builderio-qwik-distribution/* dist-dev/@builder.io-qwik/
|
||||
mkdir dist-dev/create-qwik/
|
||||
mv dist-dev-create-qwik/* dist-dev/create-qwik/
|
||||
mkdir dist-dev/eslint-plugin-qwik/
|
||||
mv dist-dev-eslint-plugin-qwik/* dist-dev/eslint-plugin-qwik/
|
||||
|
||||
- name: Cache NPM Dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: npm-cache-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
|
||||
mkdir -p packages/qwik/dist/
|
||||
mv builderio-qwik-distribution/* packages/qwik/dist/
|
||||
mkdir -p packages/create-qwik/dist/
|
||||
mv dist-dev-create-qwik/* packages/create-qwik/dist/
|
||||
mkdir -p packages/eslint-plugin-qwik/dist/
|
||||
mv dist-dev-eslint-plugin-qwik/* packages/eslint-plugin-qwik/dist/
|
||||
|
||||
- name: Install NPM Dependencies
|
||||
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
|
||||
run: yarn install --immutable --network-timeout 300000
|
||||
|
||||
- name: Dry-Run Publish @builder.io/qwik
|
||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
run: node scripts --set-dist-tag="${{ github.event.inputs.disttag }}" --release --dry-run
|
||||
run: yarn node scripts --set-dist-tag="${{ github.event.inputs.disttag }}" --release --dry-run
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Publish @builder.io/qwik
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: node scripts --set-dist-tag="${{ github.event.inputs.disttag }}" --release
|
||||
run: yarn node scripts --set-dist-tag="${{ github.event.inputs.disttag }}" --release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -419,7 +392,7 @@ jobs:
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' && github.event_name == 'push' }}
|
||||
env:
|
||||
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
|
||||
run: yarn qwik-save-artifacts
|
||||
run: yarn run qwik-save-artifacts
|
||||
|
||||
############ E2E TEST ############
|
||||
test-e2e:
|
||||
@@ -436,24 +409,29 @@ jobs:
|
||||
node: 16.x
|
||||
- host: macos-latest
|
||||
browser: webkit
|
||||
node: 14.x
|
||||
node: 16.x
|
||||
- host: windows-latest
|
||||
browser: firefox
|
||||
node: 14.x
|
||||
node: 16.x
|
||||
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
|
||||
steps:
|
||||
- name: Setup Node ${{ matrix.settings.node }}
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.settings.node }}
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- name: Checkout
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node ${{ matrix.settings.node }}
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.settings.node }}
|
||||
cache: 'yarn'
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: corepack enable
|
||||
shell: bash
|
||||
|
||||
- name: Download Build Artifacts
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
@@ -462,24 +440,16 @@ jobs:
|
||||
- name: Move Distribution Artifacts
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: |
|
||||
mkdir dist-dev/
|
||||
mkdir dist-dev/@builder.io-qwik/
|
||||
mv builderio-qwik-distribution/* dist-dev/@builder.io-qwik/
|
||||
mkdir dist-dev/create-qwik/
|
||||
mv dist-dev-create-qwik/* dist-dev/create-qwik/
|
||||
mkdir dist-dev/eslint-plugin-qwik/
|
||||
mv dist-dev-eslint-plugin-qwik/* dist-dev/eslint-plugin-qwik/
|
||||
|
||||
- name: Cache NPM Dependencies
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: npm-cache-${{ runner.os }}-node${{ matrix.settings.node }}-${{ hashFiles('yarn.lock') }}
|
||||
mkdir -p packages/qwik/dist/
|
||||
mv builderio-qwik-distribution/* packages/qwik/dist/
|
||||
mkdir -p packages/create-qwik/dist/
|
||||
mv dist-dev-create-qwik/* packages/create-qwik/dist/
|
||||
mkdir -p packages/eslint-plugin-qwik/dist/
|
||||
mv dist-dev-eslint-plugin-qwik/* packages/eslint-plugin-qwik/dist/
|
||||
|
||||
- name: Install NPM Dependencies
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
|
||||
run: yarn install --immutable --network-timeout 300000
|
||||
|
||||
- name: Install Playwright
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
@@ -487,11 +457,11 @@ jobs:
|
||||
|
||||
- name: Playwright E2E Tests
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: yarn test.e2e.${{ matrix.settings.browser }}
|
||||
run: yarn run test.e2e.${{ matrix.settings.browser }}
|
||||
|
||||
- name: Validate Create Qwik Cli
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
run: node scripts/validate-cli.cjs
|
||||
run: yarn node scripts/validate-cli.cjs
|
||||
|
||||
############ UNIT TEST ############
|
||||
test-unit:
|
||||
@@ -501,26 +471,23 @@ jobs:
|
||||
- changes
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: 'yarn'
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Cache NPM Dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: npm-cache-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
|
||||
- run: corepack enable
|
||||
|
||||
- name: Install NPM Dependencies
|
||||
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
|
||||
run: yarn install --immutable --network-timeout 300000
|
||||
|
||||
- name: Jest Unit Tests
|
||||
run: yarn test.unit
|
||||
run: yarn run test.unit
|
||||
|
||||
########### VALIDATE RUST ############
|
||||
validate-rust:
|
||||
@@ -530,9 +497,9 @@ jobs:
|
||||
needs: changes
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
- name: Checkout
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust toolchain
|
||||
if: ${{ needs.changes.outputs.fullbuild == 'true' }}
|
||||
@@ -591,21 +558,24 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Cache NPM Dependencies
|
||||
uses: actions/cache@v2
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: npm-cache-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
|
||||
node-version: 16.x
|
||||
cache: 'yarn'
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- run: corepack enable
|
||||
|
||||
- name: Install NPM Dependencies
|
||||
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
|
||||
run: yarn install --immutable --network-timeout 300000
|
||||
|
||||
- name: Prettier Check
|
||||
if: ${{ always() }}
|
||||
run: yarn lint.prettier
|
||||
run: yarn run lint.prettier
|
||||
|
||||
- name: ESLint Check
|
||||
if: ${{ always() }}
|
||||
run: yarn lint.eslint
|
||||
run: yarn run lint.eslint
|
||||
|
||||
2
.github/workflows/codeql-analysis.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
|
||||
@@ -25,5 +25,5 @@ build
|
||||
build
|
||||
node_modules
|
||||
tsconfig.tsbuildinfo
|
||||
docs/pages/
|
||||
docs/server/
|
||||
packages/docs/pages/
|
||||
packages/docs/server/
|
||||
@@ -1 +1,2 @@
|
||||
yarnPath: .yarn/releases/yarn-1.23.0-20211220.1904.cjs
|
||||
nodeLinker: node-modules
|
||||
npmPublishRegistry: 'https://registry.npmjs.org'
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
To build Qwik for local development, first [npm](https://docs.npmjs.com/) (or [yarn](https://yarnpkg.com/)) install the dev dependencies:
|
||||
|
||||
```
|
||||
npm install
|
||||
yarn install
|
||||
```
|
||||
|
||||
Next the `start` command will:
|
||||
@@ -14,7 +14,7 @@ Next the `start` command will:
|
||||
- Run the unit test (Jest) watch process
|
||||
|
||||
```
|
||||
npm start
|
||||
yarn start
|
||||
```
|
||||
|
||||
## Running All Tests
|
||||
@@ -22,7 +22,7 @@ npm start
|
||||
To run all Unit tests ([Jest](https://jestjs.io/)) and E2E tests [Playwright](https://playwright.dev/), run:
|
||||
|
||||
```
|
||||
npm test
|
||||
yarn test
|
||||
```
|
||||
|
||||
The `test` command will also ensure a build was completed.
|
||||
@@ -69,7 +69,7 @@ A full production build will:
|
||||
yarn build
|
||||
```
|
||||
|
||||
The build output will be written to `dist-dev/@builder.io-qwik`, which will be the directory that is published
|
||||
The build output will be written to `packages/qwik/dist`, which will be the directory that is published
|
||||
to [@builder.io/qwik](https://www.npmjs.com/package/@builder.io/qwik).
|
||||
|
||||
## Releasing `@builder.io/qwik`
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[workspace]
|
||||
|
||||
members = [
|
||||
"src/napi",
|
||||
"src/optimizer/cli",
|
||||
"src/optimizer/core",
|
||||
"packages/qwik/src/napi",
|
||||
"packages/qwik/src/optimizer/cli",
|
||||
"packages/qwik/src/optimizer/core",
|
||||
]
|
||||
exclude = ["src/wasm"]
|
||||
exclude = ["packages/qwik/src/wasm"]
|
||||
|
||||
[profile.release]
|
||||
debug = 0
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"name": "qwik-docs",
|
||||
"description": "Qwik Docs Site",
|
||||
"homepage": "https://qwik.builder.io/",
|
||||
"main": "src/main.tsx",
|
||||
"scripts": {
|
||||
"build": "yarn build.qwest && yarn build.client && yarn build.ssr",
|
||||
"build.client": "vite build",
|
||||
"build.ssr": "vite build --mode ssr",
|
||||
"build.qwest": "cd qwest && yarn build",
|
||||
"dev": "vite",
|
||||
"dev.ssr": "vite --mode ssr",
|
||||
"serve": "yarn build && wrangler pages dev ./dist",
|
||||
"start": "yarn dev",
|
||||
"fmt": "prettier --write .",
|
||||
"fmt.check": "prettier --check .",
|
||||
"link.builder": "npm link @builder.io/qwik"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@builder.io/partytown": "^0.5.2",
|
||||
"@builder.io/qwik": "0.0.18-dev20220422051630",
|
||||
"@cloudflare/kv-asset-handler": "0.2.0",
|
||||
"@cloudflare/workers-types": "^3.5.1",
|
||||
"@mdx-js/mdx": "^2.1.1",
|
||||
"@microsoft/api-extractor": "^7.22.2",
|
||||
"@types/github-slugger": "^1.3.0",
|
||||
"@types/marked": "^4.0.3",
|
||||
"@types/node": "^17.0.21",
|
||||
"@types/refractor": "^3.0.2",
|
||||
"@types/service-worker-mock": "2.0.1",
|
||||
"autoprefixer": "10.4.2",
|
||||
"estree-util-value-to-estree": "^1.3.0",
|
||||
"front-matter": "^4.0.2",
|
||||
"github-slugger": "^1.4.0",
|
||||
"hast-util-heading-rank": "^2.1.0",
|
||||
"hast-util-to-string": "^2.0.0",
|
||||
"history": "^5.3.0",
|
||||
"marked": "^4.0.14",
|
||||
"node-fetch": "2.6.7",
|
||||
"postcss": "8.4.6",
|
||||
"prettier": "2.3.0",
|
||||
"prism-themes": "^1.9.0",
|
||||
"refractor": "^4.5.0",
|
||||
"rehype-autolink-headings": "^6.1.1",
|
||||
"remark-frontmatter": "^4.0.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"slugify": "^1.6.5",
|
||||
"source-map": "^0.7.3",
|
||||
"tailwindcss": "3.0.18",
|
||||
"tsm": "^2.2.1",
|
||||
"typescript": "^4.6.3",
|
||||
"unified": "^10.1.2",
|
||||
"unist-util-visit": "^4.1.0",
|
||||
"uvu": "^0.5.3",
|
||||
"vfile": "^5.3.2",
|
||||
"vite": "^2.9.5",
|
||||
"wrangler": "beta"
|
||||
},
|
||||
"author": "Builder.io Team",
|
||||
"bugs": {
|
||||
"url": "https://github.com/BuilderIO/qwik"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "ES2020",
|
||||
"lib": ["es2020", "DOM"],
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "@builder.io/qwik",
|
||||
"strict": true,
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"incremental": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@builder.io/qwest": ["qwest/src/runtime/index"]
|
||||
},
|
||||
"types": ["vite/client", "@cloudflare/workers-types"]
|
||||
},
|
||||
"include": ["src", "functions", "qwest"]
|
||||
}
|
||||
2858
docs/yarn.lock
@@ -1,573 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@eslint/eslintrc@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6"
|
||||
integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.3.2"
|
||||
espree "^9.3.1"
|
||||
globals "^13.9.0"
|
||||
ignore "^5.2.0"
|
||||
import-fresh "^3.2.1"
|
||||
js-yaml "^4.1.0"
|
||||
minimatch "^3.0.4"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@humanwhocodes/config-array@^0.9.2":
|
||||
version "0.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7"
|
||||
integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==
|
||||
dependencies:
|
||||
"@humanwhocodes/object-schema" "^1.2.1"
|
||||
debug "^4.1.1"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
"@humanwhocodes/object-schema@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
||||
|
||||
"@types/eslint@^8.4.1":
|
||||
version "8.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304"
|
||||
integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==
|
||||
dependencies:
|
||||
"@types/estree" "*"
|
||||
"@types/json-schema" "*"
|
||||
|
||||
"@types/estree@*":
|
||||
version "0.0.51"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40"
|
||||
integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==
|
||||
|
||||
"@types/json-schema@*":
|
||||
version "7.0.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
|
||||
integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
|
||||
|
||||
acorn-jsx@^5.3.1:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
||||
|
||||
acorn@^8.7.0:
|
||||
version "8.7.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
|
||||
integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
|
||||
|
||||
ajv@^6.10.0, ajv@^6.12.4:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ansi-regex@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
ansi-styles@^4.1.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
callsites@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||
|
||||
chalk@^4.0.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||
dependencies:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
cross-spawn@^7.0.2:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||
dependencies:
|
||||
path-key "^3.1.0"
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
debug@^4.1.1, debug@^4.3.2:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
deep-is@^0.1.3:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||
|
||||
doctrine@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
||||
integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
escape-string-regexp@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
eslint-scope@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642"
|
||||
integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==
|
||||
dependencies:
|
||||
esrecurse "^4.3.0"
|
||||
estraverse "^5.2.0"
|
||||
|
||||
eslint-utils@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
|
||||
integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
|
||||
eslint-visitor-keys@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
|
||||
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
|
||||
|
||||
eslint-visitor-keys@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
||||
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
||||
|
||||
eslint@^8.12.0:
|
||||
version "8.12.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.12.0.tgz#c7a5bd1cfa09079aae64c9076c07eada66a46e8e"
|
||||
integrity sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==
|
||||
dependencies:
|
||||
"@eslint/eslintrc" "^1.2.1"
|
||||
"@humanwhocodes/config-array" "^0.9.2"
|
||||
ajv "^6.10.0"
|
||||
chalk "^4.0.0"
|
||||
cross-spawn "^7.0.2"
|
||||
debug "^4.3.2"
|
||||
doctrine "^3.0.0"
|
||||
escape-string-regexp "^4.0.0"
|
||||
eslint-scope "^7.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
espree "^9.3.1"
|
||||
esquery "^1.4.0"
|
||||
esutils "^2.0.2"
|
||||
fast-deep-equal "^3.1.3"
|
||||
file-entry-cache "^6.0.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
glob-parent "^6.0.1"
|
||||
globals "^13.6.0"
|
||||
ignore "^5.2.0"
|
||||
import-fresh "^3.0.0"
|
||||
imurmurhash "^0.1.4"
|
||||
is-glob "^4.0.0"
|
||||
js-yaml "^4.1.0"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.4.1"
|
||||
lodash.merge "^4.6.2"
|
||||
minimatch "^3.0.4"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.9.1"
|
||||
regexpp "^3.2.0"
|
||||
strip-ansi "^6.0.1"
|
||||
strip-json-comments "^3.1.0"
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
espree@^9.3.1:
|
||||
version "9.3.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd"
|
||||
integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==
|
||||
dependencies:
|
||||
acorn "^8.7.0"
|
||||
acorn-jsx "^5.3.1"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
esquery@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5"
|
||||
integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==
|
||||
dependencies:
|
||||
estraverse "^5.1.0"
|
||||
|
||||
esrecurse@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
|
||||
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
|
||||
dependencies:
|
||||
estraverse "^5.2.0"
|
||||
|
||||
estraverse@^5.1.0, estraverse@^5.2.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
||||
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||
|
||||
fast-levenshtein@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
|
||||
file-entry-cache@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
|
||||
integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
|
||||
dependencies:
|
||||
flat-cache "^3.0.4"
|
||||
|
||||
flat-cache@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
|
||||
integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==
|
||||
dependencies:
|
||||
flatted "^3.1.0"
|
||||
rimraf "^3.0.2"
|
||||
|
||||
flatted@^3.1.0:
|
||||
version "3.2.5"
|
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3"
|
||||
integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
functional-red-black-tree@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
||||
|
||||
glob-parent@^6.0.1:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
|
||||
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
|
||||
dependencies:
|
||||
is-glob "^4.0.3"
|
||||
|
||||
glob@^7.1.3:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
|
||||
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
globals@^13.6.0, globals@^13.9.0:
|
||||
version "13.13.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b"
|
||||
integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==
|
||||
dependencies:
|
||||
type-fest "^0.20.2"
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
ignore@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
|
||||
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
|
||||
|
||||
import-fresh@^3.0.0, import-fresh@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
|
||||
dependencies:
|
||||
parent-module "^1.0.0"
|
||||
resolve-from "^4.0.0"
|
||||
|
||||
imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||
|
||||
is-glob@^4.0.0, is-glob@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json-stable-stringify-without-jsonify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
|
||||
|
||||
levn@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
|
||||
integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
|
||||
dependencies:
|
||||
prelude-ls "^1.2.1"
|
||||
type-check "~0.4.0"
|
||||
|
||||
lodash.merge@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
optionator@^0.9.1:
|
||||
version "0.9.1"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
|
||||
integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==
|
||||
dependencies:
|
||||
deep-is "^0.1.3"
|
||||
fast-levenshtein "^2.0.6"
|
||||
levn "^0.4.1"
|
||||
prelude-ls "^1.2.1"
|
||||
type-check "^0.4.0"
|
||||
word-wrap "^1.2.3"
|
||||
|
||||
parent-module@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
|
||||
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
|
||||
dependencies:
|
||||
callsites "^3.0.0"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
|
||||
path-key@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||
|
||||
prelude-ls@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
|
||||
regexpp@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
|
||||
|
||||
resolve-from@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
||||
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
|
||||
|
||||
rimraf@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
||||
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
shebang-command@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
|
||||
dependencies:
|
||||
shebang-regex "^3.0.0"
|
||||
|
||||
shebang-regex@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
text-table@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||
|
||||
type-check@^0.4.0, type-check@~0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
||||
integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
|
||||
dependencies:
|
||||
prelude-ls "^1.2.1"
|
||||
|
||||
type-fest@^0.20.2:
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
||||
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
||||
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
v8-compile-cache@^2.0.3:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
||||
|
||||
which@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
word-wrap@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
55
output.txt
@@ -1,55 +0,0 @@
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 35 tests
|
||||
test code_move::test_fix_path ... ok
|
||||
test test::example_6 ... ok
|
||||
test test::example_13 ... ok
|
||||
test test::example_12 ... ok
|
||||
test test::example_1 ... ok
|
||||
test test::example_10 ... ok
|
||||
test test::example_3 ... ok
|
||||
test test::example_2 ... ok
|
||||
test test::example_5 ... ok
|
||||
test test::example_4 ... ok
|
||||
test test::example_11 ... ok
|
||||
test test::example_8 ... ok
|
||||
test test::example_functional_component ... ok
|
||||
test test::example_capturing_fn_class ... ok
|
||||
test test::example_7 ... ok
|
||||
test test::example_capture_imports ... ok
|
||||
test test::example_9 ... ok
|
||||
test test::example_invalid_hook_expr1 ... ok
|
||||
test test::example_functional_component_capture_props ... ok
|
||||
test test::example_custom_inlined_functions ... ok
|
||||
test test::example_functional_component_2 ... ok
|
||||
test test::example_invalid_references ... ok
|
||||
test test::example_jsx_listeners ... ok
|
||||
test test::example_jsx ... ok
|
||||
test test::example_missing_custom_inlined_functions ... ok
|
||||
test test::example_lightweight_functional ... ok
|
||||
test test::issue_117 ... ok
|
||||
test test::example_with_style ... ok
|
||||
test test::example_skip_transform ... ok
|
||||
test test::example_with_tagname ... ok
|
||||
test test::example_exports ... ok
|
||||
test test::example_renamed_exports ... ok
|
||||
test test::example_multi_capture ... ok
|
||||
test test::example_qwik_conflict ... ok
|
||||
test test::issue_118 ... ok
|
||||
|
||||
test result: ok. 35 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
192
package.json
@@ -1,22 +1,22 @@
|
||||
{
|
||||
"name": "@builder.io/qwik",
|
||||
"private": true,
|
||||
"name": "qwik-monorepo",
|
||||
"version": "0.0.19-0",
|
||||
"description": "An Open-Source sub-framework designed with a focus on server-side-rendering, lazy-loading, and styling/animation.",
|
||||
"scripts": {
|
||||
"build": "node scripts --tsc --build --api --eslint --platform-binding --wasm",
|
||||
"build.platform": "node scripts --platform-binding",
|
||||
"build.only_javascript": "node scripts --tsc --build --api",
|
||||
"build.wasm": "node scripts --wasm",
|
||||
"build.validate": "node scripts --tsc --build --api --eslint --platform-binding --wasm --validate",
|
||||
"build.cli": "node scripts --cli --dev",
|
||||
"build.cli.prod": "node scripts --cli",
|
||||
"cli": "yarn build.cli && node dist-dev/create-qwik/create-qwik",
|
||||
"build.watch": "node scripts --build --watch --dev --platform-binding",
|
||||
"api.update": "node scripts --tsc --api --dev",
|
||||
"build": "yarn node scripts --tsc --build --api --eslint --platform-binding --wasm",
|
||||
"build.platform": "yarn node scripts --platform-binding",
|
||||
"build.only_javascript": "yarn node scripts --tsc --build --api",
|
||||
"build.wasm": "yarn node scripts --wasm",
|
||||
"build.validate": "yarn node scripts --tsc --build --api --eslint --platform-binding --wasm --validate",
|
||||
"build.cli": "yarn node scripts --cli --dev",
|
||||
"build.cli.prod": "yarn node scripts --cli",
|
||||
"cli": "yarn build.cli && node packages/create-qwik/dist/create-qwik",
|
||||
"build.watch": "yarn node scripts --build --watch --dev --platform-binding",
|
||||
"api.update": "yarn node scripts --tsc --api --dev",
|
||||
"tsc.check": "tsc --noEmit",
|
||||
"tsc.watch": "tsc --noEmit --watch --preserveWatchOutput",
|
||||
"start": "concurrently \"npm:build.watch\" \"npm:test.watch\" \"npm:tsc.watch\" -n build,test,tsc -c green,magenta,cyan",
|
||||
"release.prepare": "yarn lint && yarn test.unit && node scripts --tsc --build --api --eslint --platform-binding --wasm --prepare-release",
|
||||
"release.prepare": "yarn lint && yarn test.unit && yarn node scripts --tsc --build --api --eslint --platform-binding --wasm --prepare-release",
|
||||
"test": "yarn build && jest && yarn test.e2e",
|
||||
"test.unit": "jest",
|
||||
"test.rust": "make test",
|
||||
@@ -26,9 +26,9 @@
|
||||
"test.e2e.chromium.debug": "PWDEBUG=1 playwright test starters --browser=chromium --config starters/playwright.config.ts",
|
||||
"test.e2e.firefox": "playwright test starters --browser=firefox --config starters/playwright.config.ts",
|
||||
"test.e2e.webkit": "playwright test starters --browser=webkit --config starters/playwright.config.ts",
|
||||
"serve": "node --inspect starters/dev-server.cjs 3300",
|
||||
"docs.fetch.hackMD": "node --trace-warnings -r esbuild-register scripts/docs_sync/fetch_hackmd.ts",
|
||||
"docs.sync": "node scripts/docs_sync",
|
||||
"serve": "yarn node --inspect starters/dev-server.cjs 3300",
|
||||
"docs.fetch.hackMD": "yarn node --trace-warnings -r esbuild-register scripts/docs_sync/fetch_hackmd.ts",
|
||||
"docs.sync": "yarn node scripts/docs_sync",
|
||||
"prepare": "husky install",
|
||||
"lint": "yarn lint.eslint && yarn lint.prettier && yarn lint.rust",
|
||||
"lint.eslint": "eslint \"**/*.ts*\"",
|
||||
@@ -36,111 +36,64 @@
|
||||
"lint.prettier": "prettier --check .",
|
||||
"prettier.fix": "prettier --write .",
|
||||
"fmt": "yarn prettier.fix",
|
||||
"link.dist": "cd dist-dev/@builder.io-qwik && npm link",
|
||||
"qwik-save-artifacts": "node -r esbuild-register ./scripts/qwik-save-artifacts.ts",
|
||||
"preinstall": "node scripts/tools/preinstall-script.js"
|
||||
"qwik-save-artifacts": "yarn node -r esbuild-register ./scripts/qwik-save-artifacts.ts",
|
||||
"preinstall": "yarn node scripts/tools/preinstall-script.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@builder.io/partytown": "0.5.2",
|
||||
"@builder.io/qwik-dom": "2.1.14",
|
||||
"@microsoft/api-extractor": "7.22.2",
|
||||
"@microsoft/api-extractor": "7.23.0",
|
||||
"@napi-rs/cli": "2.6.2",
|
||||
"@napi-rs/triples": "1.1.0",
|
||||
"@node-rs/helper": "1.3.3",
|
||||
"@octokit/action": "^3.18.0",
|
||||
"@octokit/action": "3.18.0",
|
||||
"@playwright/test": "1.21.1",
|
||||
"@types/cross-spawn": "6.0.2",
|
||||
"@types/eslint": "^8.4.1",
|
||||
"@types/eslint": "8.4.1",
|
||||
"@types/express": "4.17.13",
|
||||
"@types/jest": "27.4.1",
|
||||
"@types/mri": "1.1.1",
|
||||
"@types/node": "17.0.25",
|
||||
"@types/node": "17.0.29",
|
||||
"@types/path-browserify": "1.0.0",
|
||||
"@types/prompts": "2.0.14",
|
||||
"@types/semver": "^7.3.9",
|
||||
"node-fetch": "^3.2.3",
|
||||
"@types/react": "^18.0.1",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"@types/semver": "7.3.9",
|
||||
"@types/source-map-support": "0.5.4",
|
||||
"@typescript-eslint/eslint-plugin": "5.20.0",
|
||||
"@typescript-eslint/parser": "5.20.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.21.0",
|
||||
"@typescript-eslint/parser": "5.21.0",
|
||||
"concurrently": "7.1.0",
|
||||
"cross-spawn": "7.0.3",
|
||||
"esbuild": "0.14.38",
|
||||
"esbuild-register": "3.3.2",
|
||||
"eslint": "8.13.0",
|
||||
"eslint": "8.14.0",
|
||||
"eslint-plugin-no-only-tests": "2.6.0",
|
||||
"eslint-plugin-qwik": "0.0.18",
|
||||
"execa": "6.1.0",
|
||||
"express": "4.17.3",
|
||||
"gzip-size": "^6.0.0",
|
||||
"express": "4.18.0",
|
||||
"gzip-size": "6.0.0",
|
||||
"husky": "7.0.4",
|
||||
"jest": "27.5.1",
|
||||
"kleur": "4.1.4",
|
||||
"lint-staged": "12.4.0",
|
||||
"lint-staged": "12.4.1",
|
||||
"mri": "1.2.0",
|
||||
"node-fetch": "^2.0.0",
|
||||
"path-browserify": "1.0.1",
|
||||
"prettier": "2.6.2",
|
||||
"prompts": "2.4.2",
|
||||
"rollup": "2.70.2",
|
||||
"semver": "7.3.7",
|
||||
"source-map-support": "0.5.21",
|
||||
"terser": "5.12.1",
|
||||
"tailwindcss": "3.0.24",
|
||||
"terser": "5.13.0",
|
||||
"todomvc-app-css": "2.4.2",
|
||||
"todomvc-common": "1.0.5",
|
||||
"ts-jest": "27.1.4",
|
||||
"typescript": "4.6.3",
|
||||
"vite": "2.9.5",
|
||||
"vite": "2.9.6",
|
||||
"wasm-pack": "0.10.2"
|
||||
},
|
||||
"files": [
|
||||
"bindings/qwik.darwin-x64.node",
|
||||
"bindings/qwik.darwin-arm64.node",
|
||||
"bindings/qwik.win32-x64-msvc.node",
|
||||
"bindings/qwik_wasm_bg.wasm",
|
||||
"bindings/qwik.wasm.cjs",
|
||||
"bindings/qwik.wasm.mjs",
|
||||
"build/index.cjs",
|
||||
"build/index.cjs.map",
|
||||
"build/index.mjs",
|
||||
"build/index.mjs.map",
|
||||
"build/index.d.ts",
|
||||
"build/package.json",
|
||||
"core/package.json",
|
||||
"core.cjs",
|
||||
"core.cjs.map",
|
||||
"core.min.mjs",
|
||||
"core.mjs",
|
||||
"core.mjs.map",
|
||||
"core.d.ts",
|
||||
"jsx-runtime/package.json",
|
||||
"jsx-runtime.cjs",
|
||||
"jsx-runtime.cjs.map",
|
||||
"jsx-runtime.mjs",
|
||||
"jsx-runtime.mjs.map",
|
||||
"jsx-runtime.d.ts",
|
||||
"loader/index.cjs",
|
||||
"loader/index.mjs",
|
||||
"loader/index.d.ts",
|
||||
"loader/package.json",
|
||||
"optimizer/package.json",
|
||||
"optimizer.cjs",
|
||||
"optimizer.mjs",
|
||||
"optimizer.d.ts",
|
||||
"qwikloader.js",
|
||||
"qwikloader.debug.js",
|
||||
"qwikloader.optimize.js",
|
||||
"qwikloader.optimize.debug.js",
|
||||
"server.cjs",
|
||||
"server.mjs",
|
||||
"server.d.ts",
|
||||
"server/package.json",
|
||||
"testing/index.cjs",
|
||||
"testing/index.mjs",
|
||||
"testing/index.d.ts",
|
||||
"testing/package.json"
|
||||
"workspaces": [
|
||||
"packages/docs",
|
||||
"packages/create-qwik",
|
||||
"packages/qwik",
|
||||
"packages/qwik-city",
|
||||
"packages/eslint-plugin-qwik"
|
||||
],
|
||||
"contributors": [
|
||||
{
|
||||
@@ -159,31 +112,7 @@
|
||||
"url": "https://twitter.com/manucorporat"
|
||||
}
|
||||
],
|
||||
"main": "index.js",
|
||||
"@comment type": "Setting type to 'commonjs' is important as many of the bazel tooling assumes 'commonjs'. For code which wants ESM a second 'package.json' file needs to be created for just those files.",
|
||||
"type": "commonjs",
|
||||
"license": "MIT",
|
||||
"homepage": "https://qwik.builder.io/",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/BuilderIO/qwik.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/BuilderIO/qwik/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"ssr",
|
||||
"server-side-render",
|
||||
"prerender",
|
||||
"ssg",
|
||||
"static-site-generator",
|
||||
"static-site",
|
||||
"generator",
|
||||
"website",
|
||||
"webapp",
|
||||
"framework",
|
||||
"Builder.io"
|
||||
],
|
||||
"packageManager": "yarn@3.2.0",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
@@ -199,27 +128,27 @@
|
||||
"d.ts"
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"^@builder.io/qwik/jsx-runtime$": "<rootDir>/src/jsx-runtime.ts",
|
||||
"^@builder.io/qwik/optimizer$": "<rootDir>/src/optimizer/index.ts",
|
||||
"^@builder.io/qwik/server$": "<rootDir>/src/server/index.ts",
|
||||
"^@builder.io/qwik/testing$": "<rootDir>/src/testing/index.ts",
|
||||
"^@builder.io/qwik/build$": "<rootDir>/src/build/index.ts",
|
||||
"^@builder.io/qwik$": "<rootDir>/src/core/index.ts"
|
||||
"^@builder.io/qwik/jsx-runtime$": "<rootDir>/packages/qwik/src/jsx-runtime.ts",
|
||||
"^@builder.io/qwik/optimizer$": "<rootDir>/packages/qwik/src/optimizer/index.ts",
|
||||
"^@builder.io/qwik/server$": "<rootDir>/packages/qwik/src/server/index.ts",
|
||||
"^@builder.io/qwik/testing$": "<rootDir>/packages/qwik/src/testing/index.ts",
|
||||
"^@builder.io/qwik/build$": "<rootDir>/packages/qwik/src/build/index.ts",
|
||||
"^@builder.io/qwik$": "<rootDir>/packages/qwik/src/core/index.ts"
|
||||
},
|
||||
"modulePathIgnorePatterns": [
|
||||
"<rootDir>/.github/",
|
||||
"<rootDir>/.husky/",
|
||||
"<rootDir>/.vscode/",
|
||||
"<rootDir>/src/cli/",
|
||||
"<rootDir>/src/napi/",
|
||||
"<rootDir>/src/optimizer/cli/",
|
||||
"<rootDir>/src/optimizer/core/",
|
||||
"<rootDir>/src/wasm/",
|
||||
"<rootDir>/packages/qwik/src/cli/",
|
||||
"<rootDir>/packages/qwik/src/napi/",
|
||||
"<rootDir>/packages/qwik/src/optimizer/cli/",
|
||||
"<rootDir>/packages/qwik/src/optimizer/core/",
|
||||
"<rootDir>/packages/qwik/src/wasm/",
|
||||
"<rootDir>/packages/qwik-city/",
|
||||
"<rootDir>/dist",
|
||||
"<rootDir>/dist-dev",
|
||||
"<rootDir>/starters",
|
||||
"<rootDir>/node_modules",
|
||||
"<rootDir>/starters",
|
||||
"<rootDir>/target"
|
||||
],
|
||||
"testPathIgnorePatterns": [
|
||||
@@ -227,20 +156,21 @@
|
||||
"<rootDir>/.husky/",
|
||||
"<rootDir>/.vscode/",
|
||||
"<rootDir>/bin/",
|
||||
"<rootDir>/src/cli/",
|
||||
"<rootDir>/src/napi/",
|
||||
"<rootDir>/src/optimizer/cli/",
|
||||
"<rootDir>/src/optimizer/core/",
|
||||
"<rootDir>/src/wasm/",
|
||||
"<rootDir>/dist/",
|
||||
"<rootDir>/packages/create-qwik/",
|
||||
"<rootDir>/packages/qwik/dist/",
|
||||
"<rootDir>/packages/qwik/src/napi/",
|
||||
"<rootDir>/packages/qwik/src/optimizer/cli/",
|
||||
"<rootDir>/packages/qwik/src/optimizer/core/",
|
||||
"<rootDir>/packages/qwik/src/wasm/",
|
||||
"<rootDir>/packages/docs/",
|
||||
"<rootDir>/dist-dev/",
|
||||
"<rootDir>/docs/",
|
||||
"<rootDir>/starters/",
|
||||
"<rootDir>/node_modules",
|
||||
".*/node_modules/",
|
||||
".*/dist/",
|
||||
"<rootDir>/target/"
|
||||
],
|
||||
"testRegex": "/(scripts|src|eslint-rules)/.*\\.unit\\.(ts|tsx)$"
|
||||
"testRegex": "/(scripts|packages)/.*\\.unit\\.(ts|tsx)$"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.*": [
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
"name": "create-qwik",
|
||||
"version": "0.0.19-0",
|
||||
"description": "Interactive CLI and API for generating Qwik projects.",
|
||||
"bin": {
|
||||
"create-qwik": "create-qwik"
|
||||
},
|
||||
"bin": "create-qwik",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
"create-qwik",
|
||||
@@ -20,11 +18,17 @@
|
||||
"homepage": "https://qwik.builder.io/",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/BuilderIO/qwik.git"
|
||||
"url": "https://github.com/BuilderIO/qwik.git",
|
||||
"directory": "packages/create-qwik"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/BuilderIO/qwik/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/prompts": "2.0.14",
|
||||
"kleur": "4.1.4",
|
||||
"prompts": "2.4.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14",
|
||||
"npm": ">=6.0.0"
|
||||
4
docs/.gitignore → packages/docs/.gitignore
vendored
@@ -2,8 +2,8 @@
|
||||
.mf
|
||||
.vscode
|
||||
.rollup.cache
|
||||
/server
|
||||
/dist
|
||||
server
|
||||
dist
|
||||
node_modules
|
||||
tsconfig.tsbuildinfo
|
||||
q-symbols.json
|
||||
69
packages/docs/package.json
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"name": "qwik-docs",
|
||||
"version": "0.0.1",
|
||||
"description": "Qwik Docs Site",
|
||||
"homepage": "https://qwik.builder.io/",
|
||||
"main": "src/main.tsx",
|
||||
"scripts": {
|
||||
"build": "yarn build.qwikcity && yarn build.client && yarn build.ssr",
|
||||
"build.client": "vite build",
|
||||
"build.ssr": "vite build --mode ssr",
|
||||
"build.qwikcity": "cd ../qwik-city && yarn build",
|
||||
"dev": "vite --force",
|
||||
"dev.ssr": "vite --mode ssr",
|
||||
"serve": "yarn build && wrangler pages dev ./dist",
|
||||
"start": "yarn dev",
|
||||
"fmt": "prettier --write .",
|
||||
"fmt.check": "prettier --check ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@builder.io/partytown": "^0.5.2",
|
||||
"@builder.io/qwik": "0.0.19-0",
|
||||
"@builder.io/qwik-city": "workspace:*",
|
||||
"@cloudflare/kv-asset-handler": "0.2.0",
|
||||
"@cloudflare/workers-types": "^3.7.1",
|
||||
"@mdx-js/mdx": "^2.1.1",
|
||||
"@microsoft/api-extractor": "^7.23.0",
|
||||
"@types/github-slugger": "^1.3.0",
|
||||
"@types/marked": "^4.0.3",
|
||||
"@types/mdx": "2.0.1",
|
||||
"@types/node": "17.0.29",
|
||||
"@types/refractor": "3.0.2",
|
||||
"autoprefixer": "10.4.5",
|
||||
"estree-util-value-to-estree": "1.3.0",
|
||||
"front-matter": "4.0.2",
|
||||
"github-slugger": "1.4.0",
|
||||
"hast-util-heading-rank": "2.1.0",
|
||||
"hast-util-to-string": "2.0.0",
|
||||
"history": "5.3.0",
|
||||
"marked": "4.0.14",
|
||||
"node-fetch": "2.6.7",
|
||||
"postcss": "8.4.12",
|
||||
"prettier": "2.6.2",
|
||||
"prism-themes": "1.9.0",
|
||||
"refractor": "^4.6.0",
|
||||
"rehype-autolink-headings": "6.1.1",
|
||||
"remark-frontmatter": "4.0.1",
|
||||
"remark-gfm": "3.0.1",
|
||||
"slugify": "1.6.5",
|
||||
"source-map": "0.7.3",
|
||||
"tailwindcss": "3.0.24",
|
||||
"tsm": "2.2.1",
|
||||
"typescript": "4.6.3",
|
||||
"unified": "10.1.2",
|
||||
"unist-util-visit": "4.1.0",
|
||||
"uvu": "0.5.3",
|
||||
"vfile": "5.3.2",
|
||||
"vite": "2.9.6",
|
||||
"wrangler": "beta"
|
||||
},
|
||||
"author": "Builder.io Team",
|
||||
"bugs": {
|
||||
"url": "https://github.com/BuilderIO/qwik"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
@@ -10,12 +10,12 @@ The host element is an element in the DOM that represents component boundaries.
|
||||
Lite-components do not have host elements.
|
||||
|
||||
```tsx
|
||||
const Child = () => (
|
||||
<span>child</span>
|
||||
);
|
||||
const Child = () => <span>child</span>;
|
||||
|
||||
const Parent = () => (
|
||||
<section><Child/></section>
|
||||
<section>
|
||||
<Child />
|
||||
</section>
|
||||
);
|
||||
```
|
||||
|
||||
@@ -32,12 +32,12 @@ Looking at the resulting HTML, it is not possible to tell if a single component
|
||||
On the other hand, Qwik-components rely on host elements because it must be possible by looking on the HTML to determine where one component starts and another ends. Without knowing the boundaries, it would not be possible to render components independently without forcing parent/child components to render as well. This is a crucial feature of Qwik.
|
||||
|
||||
```tsx
|
||||
const Child = component$(() => (
|
||||
<span>child</span>
|
||||
));
|
||||
const Child = component$(() => <span>child</span>);
|
||||
|
||||
const Parent = component$(() => (
|
||||
<section><Child /></section>
|
||||
<section>
|
||||
<Child />
|
||||
</section>
|
||||
));
|
||||
```
|
||||
|
||||
@@ -60,12 +60,12 @@ Qwik host elements are marked with `q:host` attribute. (Default element is `div`
|
||||
The host component also serves an important role when breaking parent-child relationships for bundling purposes.
|
||||
|
||||
```tsx
|
||||
const Child = () => (
|
||||
<span>child</span>
|
||||
);
|
||||
const Child = () => <span>child</span>;
|
||||
|
||||
const Parent = () => (
|
||||
<section><Child/></section>
|
||||
<section>
|
||||
<Child />
|
||||
</section>
|
||||
);
|
||||
```
|
||||
|
||||
@@ -73,9 +73,7 @@ In the above example, referring to the `Parent` component implies a transitive r
|
||||
|
||||
```tsx
|
||||
const Child = component$(() => {
|
||||
return (
|
||||
<span>child</span>
|
||||
);
|
||||
return <span>child</span>;
|
||||
});
|
||||
|
||||
const Parent = component$(() => {
|
||||
@@ -93,7 +91,11 @@ In the above example the Optimizer transforms the above to:
|
||||
const Child = component$(qrl('./chunk-a', 'Child_onMount'));
|
||||
const Parent = component$(qrl('./chunk-b', 'Parent_onMount'));
|
||||
const Parent_onMount = () => qrl('./chunk-c', 'Parent_onRender');
|
||||
const Parent_onRender = () => <section><Child/></section>;
|
||||
const Parent_onRender = () => (
|
||||
<section>
|
||||
<Child />
|
||||
</section>
|
||||
);
|
||||
```
|
||||
|
||||
NOTE: for simplicity, not all of the transformations are shown; all resulting symbols are kept in the same file for succinctness.
|
||||
@@ -149,11 +151,7 @@ Because the host element is an actual element, there may be a desire to place HT
|
||||
What if you wanted to add a `name` attribute to the host element? The issue is that the `name` is already used by the component props. For this reason, we use `host:` prefix to refer to the host element's attributes.
|
||||
|
||||
```tsx
|
||||
<Greeter
|
||||
host:name="abc"
|
||||
host:id="greeter"
|
||||
host:onClick$={() => {}}
|
||||
name="world" />
|
||||
<Greeter host:name="abc" host:id="greeter" host:onClick$={() => {}} name="world" />
|
||||
```
|
||||
|
||||
would render as:
|
||||
@@ -167,10 +165,7 @@ Using an `host:` prefix allows the developer to control the component's host ele
|
||||
One can use the same approach for `class` and `styles`.
|
||||
|
||||
```tsx
|
||||
<Greeter
|
||||
host:class="greeter"
|
||||
host:style={{backgroundColor: 'red'}}
|
||||
name="world" />
|
||||
<Greeter host:class="greeter" host:style={{ backgroundColor: 'red' }} name="world" />
|
||||
```
|
||||
|
||||
would render:
|
||||
@@ -179,13 +174,11 @@ would render:
|
||||
<div q:host class="greeter" style="background-color: red;"></div>
|
||||
```
|
||||
|
||||
However, many IDEs will not recognize `host:class` and `host:style` and would not trigger code completion. For this reason, `class` and `styles` are special, and they will automatically map to `host:class` and `host:styles`
|
||||
However, many IDEs will not recognize `host:class` and `host:style` and would not trigger code completion. For this reason, `class` and `styles` are special, and they will automatically map to `host:class` and `host:styles`
|
||||
when placed on the host element.
|
||||
|
||||
```jsx
|
||||
<Greeter class="greeter"
|
||||
style={{backgroundColor: 'red'}}
|
||||
name="world"/>
|
||||
<Greeter class="greeter" style={{ backgroundColor: 'red' }} name="world" />
|
||||
```
|
||||
|
||||
would also render to the some output.
|
||||
@@ -19,11 +19,7 @@ Qwik components are declared with `component$` API.
|
||||
const Counter = component$((props: { step?: number; initial?: number }) => {
|
||||
const store = useStore({ count: props.initial || 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={() => store.count += props.step||1}>
|
||||
{store.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={() => (store.count += props.step || 1)}>{store.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -70,13 +66,9 @@ Events handlers are closures placed in the JSX.
|
||||
|
||||
```tsx
|
||||
const Counter = component$(() => {
|
||||
const store = useStore({count: 0});
|
||||
const store = useStore({ count: 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={() => store.count++}>
|
||||
{store.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={() => store.count++}>{store.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -15,11 +15,10 @@ const Collapsible = component$(() => {
|
||||
|
||||
return (
|
||||
<div class="collapsible">
|
||||
<div class="title"
|
||||
onClick$={() => store.isOpen = !store.isOpen}>
|
||||
<div class="title" onClick$={() => (store.isOpen = !store.isOpen)}>
|
||||
<Slot name="title"></Slot>
|
||||
</div>
|
||||
{store.isOpen ? <Slot/> : null}
|
||||
{store.isOpen ? <Slot /> : null}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -32,8 +31,7 @@ const MyApp = component$(() => {
|
||||
return (
|
||||
<Collapsible>
|
||||
<span q:slot="title">Title text</span>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
Vivamus vulputate accumsan pretium.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus vulputate accumsan pretium.
|
||||
</Collapsible>
|
||||
);
|
||||
});
|
||||
@@ -52,8 +50,7 @@ The above example would render into this HTML if `isOpen===true`:
|
||||
<span q:slot="title" has-content>Title text</span>
|
||||
</q:slot>
|
||||
<q:slot>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
Vivamus vulputate accumsan pretium.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus vulputate accumsan pretium.
|
||||
</q:slot>
|
||||
</collapsible>
|
||||
</my-app>
|
||||
@@ -159,17 +156,11 @@ Qwik keeps all content around, even if not projected. This is because the conten
|
||||
|
||||
```tsx
|
||||
const Project = component$(() => {
|
||||
return (
|
||||
<div />
|
||||
);
|
||||
return <div />;
|
||||
});
|
||||
|
||||
const MyApp = component$(() => {
|
||||
return (
|
||||
<Project>
|
||||
unwrapped text
|
||||
</Project>
|
||||
);
|
||||
return <Project>unwrapped text</Project>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -198,14 +189,10 @@ const Project = component$(() => {
|
||||
<Slot>default content</Slot>
|
||||
</>
|
||||
);
|
||||
})
|
||||
});
|
||||
|
||||
const MyApp = component$(() => {
|
||||
return (
|
||||
<Project>
|
||||
some content
|
||||
</Project>
|
||||
);
|
||||
return <Project>some content</Project>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -233,14 +220,14 @@ On order for Qwik to be able to render components independently, it must be able
|
||||
|
||||
```html
|
||||
<style>
|
||||
q:slot,q:slot-default {
|
||||
/** This marks the extra elements inert for flex, etc... **/
|
||||
display: contents;
|
||||
}
|
||||
q:slot.has-content > q:slot-default {
|
||||
/** Suppress the default value of Slot if parent provided content **/
|
||||
display: none:
|
||||
}
|
||||
q:slot,q:slot-default {
|
||||
/** This marks the extra elements inert for flex, etc... **/
|
||||
display: contents;
|
||||
}
|
||||
q:slot.has-content > q:slot-default {
|
||||
/** Suppress the default value of Slot if parent provided content **/
|
||||
display: none:
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
@@ -27,12 +27,9 @@ The resulting component can be used like so:
|
||||
const MyApp = component$(() => {
|
||||
return (
|
||||
<>
|
||||
- With no props: <Item/>
|
||||
- With some props: <Item description="Item description"/>
|
||||
- With all props: <Item name="Hammer"
|
||||
quantity={3}
|
||||
description="Best organic hammer"
|
||||
price={10.00} />
|
||||
- With no props: <Item />
|
||||
- With some props: <Item description="Item description" />- With all props:{' '}
|
||||
<Item name="Hammer" quantity={3} description="Best organic hammer" price={10.0} />
|
||||
</>
|
||||
);
|
||||
});
|
||||
@@ -79,9 +76,7 @@ When re-rendering a component, the child component props can stay the same or be
|
||||
|
||||
```tsx
|
||||
const Child = component$((props: { count: number }) => {
|
||||
return (
|
||||
<span>{props.count}</span>
|
||||
);
|
||||
return <span>{props.count}</span>;
|
||||
});
|
||||
|
||||
const MyApp = component$(() => {
|
||||
@@ -42,14 +42,10 @@ Let's look at an example of how all of the pieces of the QRL tie together.
|
||||
The developer writes code for a simple component.
|
||||
|
||||
```tsx
|
||||
const Counter = component$((props: {step: number}) => {
|
||||
const state = createState({count: 0});
|
||||
const Counter = component$((props: { step: number }) => {
|
||||
const state = createState({ count: 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={state.count += props.step || 1}>
|
||||
{state.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={(state.count += props.step || 1)}>{state.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -100,14 +96,14 @@ Assume: `http://localhost/index.html`
|
||||
<html>
|
||||
<body q:base="/build/">
|
||||
<div q:id="123" q:obj="456" q:host>
|
||||
<button
|
||||
q:obj="456, 123"
|
||||
onClickQrl="./chunk-c.js#Counter_onClick[0,1]">
|
||||
0
|
||||
</button>
|
||||
<button q:obj="456, 123" onClickQrl="./chunk-c.js#Counter_onClick[0,1]">0</button>
|
||||
</div>
|
||||
<script>/*Qwikloader script*/</script>
|
||||
<script type="qwik/json">{...json...}</script>
|
||||
<script>
|
||||
/*Qwikloader script*/
|
||||
</script>
|
||||
<script type="qwik/json">
|
||||
{...json...}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -4,16 +4,16 @@ title: Containers
|
||||
|
||||
# Containers
|
||||
|
||||
***NOTE**: Work in progress / Not fully implemented*
|
||||
**\*NOTE**: Work in progress / Not fully implemented\*
|
||||
|
||||
Containers are a way to break up an application into smaller parts. We call these parts containers. Containers bring several benefits. Each container on the page can independently be:
|
||||
|
||||
- **resumed**: Each container can be resumed independently from all other components on the page. Independent resumability further reduces the amount of state which resume deserializes.
|
||||
- **updated**: Each container can be updated/replaced at any point using `innerHTML`. This allows a portion of the page to update without forcing a full re-fetch of a complete HTML document without downloading or executing JavaScript.
|
||||
- **updated**: Each container can be updated/replaced at any point using `innerHTML`. This allows a portion of the page to update without forcing a full re-fetch of a complete HTML document without downloading or executing JavaScript.
|
||||
- **compiled**: Each container can be compiled and deployed separately from other containers. Separate compilation is especially useful for large-scale applications and large-scale teams working on the applications.
|
||||
- **versioned**: Each container can run a different version of the Qwik framework. Allowing for the composability of the website from many small containers.
|
||||
|
||||
Containers can be nested in a tree and can communicate and share data. The inter-component communication requires that the components have well-defined boundaries, which we call container protocols.
|
||||
|
||||
Containers can be nested in a tree and can communicate and share data. The inter-component communication requires that the components have well-defined boundaries, which we call container protocols.
|
||||
|
||||
## Containers vs. Components
|
||||
|
||||
@@ -24,9 +24,9 @@ Containers sound very similar to components; what are the differences? You can t
|
||||
- Containers can't modify the state which has been passed into them.
|
||||
|
||||
Components have restrictions:
|
||||
- Components must be compiled together and, as a result, share the same bundle artifacts and same Qwik version.
|
||||
- On pause, all of the components in the container are serialized together (and then they are resumed together.)
|
||||
|
||||
- Components must be compiled together and, as a result, share the same bundle artifacts and same Qwik version.
|
||||
- On pause, all of the components in the container are serialized together (and then they are resumed together.)
|
||||
|
||||
## What do containers solve?
|
||||
|
||||
@@ -37,15 +37,16 @@ Containers allow multiple independent Qwik applications to run on the page and b
|
||||
|
||||
### Routing
|
||||
|
||||
A typical site is composed of two logical parts:
|
||||
1. The navigation that tends to stay constant across many pages, and
|
||||
2. The outlet, which is the part of the page that changes based on which route the user navigated to.
|
||||
A typical site is composed of two logical parts:
|
||||
|
||||
1. The navigation that tends to stay constant across many pages, and
|
||||
2. The outlet, which is the part of the page that changes based on which route the user navigated to.
|
||||
|
||||
We can model the two parts as two navigation and outlet containers. When the user first navigates to a route, the server responds with HTML, which contains containers for both the navigation and the outlet. Once the user navigates to the second route, there are three ways to solve the navigation:
|
||||
|
||||
1. The simplistic approach is to make a full round trip and download an entirely new page. The main downside is that the application loses all of its states on the client.
|
||||
1. The simplistic approach is to make a full round trip and download an entirely new page. The main downside is that the application loses all of its states on the client.
|
||||
1. The classical approach is to treat any further navigation in JavaScript. We replace the current outlet component with the new outlet component and let the new component render. The disadvantage is that we need to download and execute the JavaScript.
|
||||
2. The Qwik approach treats the navigation and the outlet as two different containers. The first navigation downloads HTML representing the full page (with both containers.) The subsequent navigation fetches the HTML only for the outlet container. This approach is the best of both worlds. The navigation is fast (no JavaScript download or execution), and the application keeps its state in the parent container.
|
||||
1. The Qwik approach treats the navigation and the outlet as two different containers. The first navigation downloads HTML representing the full page (with both containers.) The subsequent navigation fetches the HTML only for the outlet container. This approach is the best of both worlds. The navigation is fast (no JavaScript download or execution), and the application keeps its state in the parent container.
|
||||
|
||||
### Micro-frontend
|
||||
|
||||
@@ -53,6 +54,6 @@ When an application gets very large, it becomes impractical to think of it as a
|
||||
|
||||
For large apps, the teams also become large. Large teams usually have different goals and, as a result, different release schedules.
|
||||
|
||||
Containers allow a large team to break up the application into many smaller parts and treat each part as a unit with a separate deployment, testing, and version upgrade schedule.
|
||||
Containers allow a large team to break up the application into many smaller parts and treat each part as a unit with a separate deployment, testing, and version upgrade schedule.
|
||||
|
||||
Teams break up the application into containers and clearly define protocols between the containers. As long as the protocols are satisfied, each team can deploy the two containers independently.
|
||||
Teams break up the application into containers and clearly define protocols between the containers. As long as the protocols are satisfied, each team can deploy the two containers independently.
|
||||
@@ -17,12 +17,8 @@ const Counter = component$(() => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button onClick$={() => store.htmlCount++}>
|
||||
{store.count}
|
||||
</button>
|
||||
<CmpButton onClick$={() => store.cmpCount++}>
|
||||
{store.count}
|
||||
</CmpButton>
|
||||
<button onClick$={() => store.htmlCount++}>{store.count}</button>
|
||||
<CmpButton onClick$={() => store.cmpCount++}>{store.count}</CmpButton>
|
||||
</>
|
||||
);
|
||||
});
|
||||
@@ -44,23 +40,22 @@ Notice that both `<button>` and `<CmpButton>` use the same syntax for registerin
|
||||
|
||||
The main point here is that while the syntax of the events is consistent between HTML elements and Components, the resulting HTML only has `on:<event>` attributes for the DOM events, not for the component props.
|
||||
|
||||
|
||||
## Declaring Component Events
|
||||
|
||||
So far, we have ignored the implementation detail of `<CmpButton>` because we wanted to talk about its usage only. Now let's look at how one declares a child component that can be used with events.
|
||||
|
||||
```tsx
|
||||
interface CmpButtonProps {
|
||||
onClickQrl?: QRL<() => void>;
|
||||
}
|
||||
interface CmpButtonProps {
|
||||
onClickQrl?: QRL<() => void>;
|
||||
}
|
||||
|
||||
const CmpButton = component$((props: CmpButtonProps) => {
|
||||
return (
|
||||
<button onDblclickQrl={props.onClickQrl}>
|
||||
<Slot />
|
||||
</button>
|
||||
);
|
||||
});
|
||||
const CmpButton = component$((props: CmpButtonProps) => {
|
||||
return (
|
||||
<button onDblclickQrl={props.onClickQrl}>
|
||||
<Slot />
|
||||
</button>
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
As far as Qwik is concerned, passing events to a component is equivalent to passing props. In our example, we declare all props in `CmpButtonProps` interface. Specifically, notice `onClickQrl?: QRL<() => void>` declaration.
|
||||
@@ -70,9 +65,7 @@ As far as Qwik is concerned, passing events to a component is equivalent to pass
|
||||
On the usage side, when referring to the `<CmpButton>`, it would be a lot more convenient to pass in a closure rather than `QRL` of the closure. The translation from closure to`QRL` closure is what Qwik Optimizer performs for us. For this reason, the usage is in the format where the closure is inlined like so:
|
||||
|
||||
```tsx
|
||||
<CmpButton onClick$={() => store.cmpCount++}>
|
||||
{store.count}
|
||||
</CmpButton>
|
||||
<CmpButton onClick$={() => store.cmpCount++}>{store.count}</CmpButton>
|
||||
```
|
||||
|
||||
Here the prop is `onClick$` rather than `onClickQrl`. We rely on the Qwik Optimizer to perform the translation. The above is roughly translated to:
|
||||
@@ -84,14 +77,16 @@ Here the prop is `onClick$` rather than `onClickQrl`. We rely on the Qwik Optimi
|
||||
```
|
||||
|
||||
Assume: `chunk-a.js`:
|
||||
|
||||
```tsx
|
||||
export const Counter_onRender_CmpButton_onClick = () => {
|
||||
const [store] = useLexicalScope();
|
||||
store.cmpCount++;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Notice that:
|
||||
|
||||
- `onClick$` was translated to `onClickQrl`.
|
||||
- The closure `() => store.cmpCount++` was replaced by `qrl('./chunk-a.js', 'Counter_onRender_CmpButton_onClick', [state]`.
|
||||
- The closure was exported as `Counter_onRender_CmpButton_onClick`.
|
||||
@@ -106,30 +101,32 @@ interface CmpButtonProps {
|
||||
}
|
||||
```
|
||||
|
||||
Notice that TypeScript automatically creates a correct prop with `$` suffix, which generates the parameterized `T` of `QRL<T>`. In our case `T` is `() => void`. This type information makes sure that you correctly pass `QRL` to `on<event>Qrl` suffix and closures to `on<event>$` suffix.
|
||||
Notice that TypeScript automatically creates a correct prop with `$` suffix, which generates the parameterized `T` of `QRL<T>`. In our case `T` is `() => void`. This type information makes sure that you correctly pass `QRL` to `on<event>Qrl` suffix and closures to `on<event>$` suffix.
|
||||
|
||||
## Working with QRLs
|
||||
|
||||
Let's look at a variation of `<CmpButton>` implementation. In this example, we would like to demonstrate working with `<prop>Qrl` vs `<prop>$`. For this reason, we have created an additional listener `onClick$`
|
||||
|
||||
```tsx
|
||||
interface CmpButtonProps {
|
||||
onClickQrl?: QRL<() => void>;
|
||||
}
|
||||
interface CmpButtonProps {
|
||||
onClickQrl?: QRL<() => void>;
|
||||
}
|
||||
|
||||
const CmpButton = component$((props: CmpButtonProps) => {
|
||||
return (
|
||||
<button onDblclickQrl={props.onClickQrl}
|
||||
onClick$={async () => {
|
||||
await (props.onClickQrl && props.onClickQrl.invoke());
|
||||
console.log("clicked");
|
||||
}}>
|
||||
<Slot />
|
||||
</button>
|
||||
);
|
||||
});
|
||||
const CmpButton = component$((props: CmpButtonProps) => {
|
||||
return (
|
||||
<button
|
||||
onDblclickQrl={props.onClickQrl}
|
||||
onClick$={async () => {
|
||||
await (props.onClickQrl && props.onClickQrl.invoke());
|
||||
console.log('clicked');
|
||||
}}
|
||||
>
|
||||
<Slot />
|
||||
</button>
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
Notice that we can pass the `props.onClickQrl` directly to the `onDblclickQrl` as seen on `<button>`. (see attribute `onDblclickQrl={props.onClickQrl}`.) This is because both the inputting prop `onClickQrl` as well as JSX prop `onDblclickQrl` are of type `QRL<?>` (and both have `Qrl` suffix.)
|
||||
|
||||
However, it is not possible to pass `props.onClickQrl` to `onClick$` because the types don't match. (This would result in type error: `onClick$={props.onClickQrl}`.) Instead, the `$` is reserved for inlined closures. In our example, we would like to print the `console.log("clicked")` after we process the `props.onClickQrl` callback. We can do so with the `props.onClickQrl.invoke()` method. This 1) lazy-loads the code, 2) restores the closure state, and 3) invokes the closure. The operation is asynchronous and therefore returns a promise, which we can resolve using the `await` statement.
|
||||
However, it is not possible to pass `props.onClickQrl` to `onClick$` because the types don't match. (This would result in type error: `onClick$={props.onClickQrl}`.) Instead, the `$` is reserved for inlined closures. In our example, we would like to print the `console.log("clicked")` after we process the `props.onClickQrl` callback. We can do so with the `props.onClickQrl.invoke()` method. This 1) lazy-loads the code, 2) restores the closure state, and 3) invokes the closure. The operation is asynchronous and therefore returns a promise, which we can resolve using the `await` statement.
|
||||
@@ -34,4 +34,4 @@ const EventExample = component$(() => {
|
||||
The purpose of the `onWindow`/`onDocument` is to register the event at a current DOM location of the component but have it receive events from the `window`/`document`. There are two advantages to it:
|
||||
|
||||
1. The events can be registered declaratively in your JSX
|
||||
2. The events get automatically cleaned up when the component is destroyed. (No explicit bookkeeping and cleanup is needed.)
|
||||
2. The events get automatically cleaned up when the component is destroyed. (No explicit bookkeeping and cleanup is needed.)
|
||||
@@ -8,13 +8,9 @@ For a web application to be interactive, there needs to be a way to respond to u
|
||||
|
||||
```tsx
|
||||
const Counter = component$(() => {
|
||||
const store = useStore({count: 0});
|
||||
const store = useStore({ count: 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={() => store.count++}>
|
||||
{store.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={() => store.count++}>{store.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -22,27 +18,22 @@ In the above example, the `onClick$` attribute of the `<button>` element is used
|
||||
|
||||
Notice that `onClick$` ends with `$`. This is a hint to both the Qwik Optimizer and the developer that a special transformation occurs at this location. The presence of the `$` suffix implies a lazy-loaded boundary here. The code associated with the `click` handler will not download until the user triggers the `click` event. See: [Optimizer Rules](../optimizer/dollar.mdx) for more details.
|
||||
|
||||
In the above example, the `click` listener is trivial in implementation. But in real applications, the listener may refer to complex code. By creating a lazy-loaded boundary, Qwik can tree-shake all of the code behind the click listener and delay its loading until the user clicks on the event.
|
||||
|
||||
In the above example, the `click` listener is trivial in implementation. But in real applications, the listener may refer to complex code. By creating a lazy-loaded boundary, Qwik can tree-shake all of the code behind the click listener and delay its loading until the user clicks on the event.
|
||||
|
||||
## DOM
|
||||
|
||||
```tsx
|
||||
const Counter = component$(() => {
|
||||
const store = useStore({count: 0});
|
||||
const store = useStore({ count: 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={() => store.count++}>
|
||||
{store.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={() => store.count++}>{store.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
In the above example, the `onClick$` is placed on `<button>`. This means that the listener needs to be registered with the DOM. The registration of the listener creates two problems in the context of the SSR/SSG that Qwik needs to solve. (For context, remember that Qwik is resumable, that is, it can continue executing the application from where the server paused without being forced to download and execute code eagerly.)
|
||||
|
||||
1. **listener location**: Qwik needs to know where the events are in the HTML which came from the SSR/SSG.
|
||||
2. **listener code**: Qwik needs to know what code should run if the event is triggered.
|
||||
1. **listener location**: Qwik needs to know where the events are in the HTML which came from the SSR/SSG.
|
||||
2. **listener code**: Qwik needs to know what code should run if the event is triggered.
|
||||
|
||||
Without the above information, Qwik would be forced to download the component template and execute it so that the listener location and closure can be recovered. This process is known as hydration, and Qwik explicitly tries to avoid hydration.
|
||||
|
||||
@@ -54,7 +45,7 @@ Qwik serializes the event listeners into DOM in the form of [QRLs](../components
|
||||
</div>
|
||||
```
|
||||
|
||||
The critical thing to notice is that Qwik generated an `on:click` attribute, containing the value `./chunk-a.js#Counter_button_onClick[0]`. In the above example the `on:click` attribute solves the listener location problem, and the attribute value solves the listener code location problem. By serializing the listeners into the HTML Qwik, applications do not need to perform hydration on application startup.
|
||||
The critical thing to notice is that Qwik generated an `on:click` attribute, containing the value `./chunk-a.js#Counter_button_onClick[0]`. In the above example the `on:click` attribute solves the listener location problem, and the attribute value solves the listener code location problem. By serializing the listeners into the HTML Qwik, applications do not need to perform hydration on application startup.
|
||||
|
||||
## Qwikloader
|
||||
|
||||
@@ -68,17 +59,13 @@ When a user interacts with the application, the browser fires relevant events th
|
||||
const Counter = component$(() => {
|
||||
const store = useStore({ count: 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={() => store.count++}>
|
||||
{store.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={() => store.count++}>{store.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
At first sight, it may appear that the Qwik simply lazy loads the `onClick$` function. But upon closer inspection, it is important to realize that the Qwik lazy loads a closure rather than a function. (A closure is a function that lexically captures the state inside its variables. In other words, closures carry state, whereas functions do not.) The capturing of the state is what allows the Qwik application to simply resume where the server left off because the recovered closure carries the state of the application with it.
|
||||
|
||||
In our case, the `onClick$` closure captures `store`. Capturing of `store` allows the application to increment the `count` property on `click` without having to re-run the whole application. Let's look at how closure capturing works in Qwik.
|
||||
In our case, the `onClick$` closure captures `store`. Capturing of `store` allows the application to increment the `count` property on `click` without having to re-run the whole application. Let's look at how closure capturing works in Qwik.
|
||||
|
||||
The HTML generated by the above code is something like this:
|
||||
|
||||
@@ -89,9 +76,10 @@ The HTML generated by the above code is something like this:
|
||||
```
|
||||
|
||||
Notice that `on:click` attribute contains three pieces of information:
|
||||
|
||||
1. `./chunk-a.js`: The file which needs to be lazy-loaded.
|
||||
2. `Counter_button_onClick`: The symbol which needs to be retrieved from the lazy-loaded chunk.
|
||||
3. `[0]`: An array of lexically capture variable references (State of the closure).
|
||||
3. `[0]`: An array of lexically capture variable references (State of the closure).
|
||||
|
||||
In our case `() => store.count++` only captures `store`, and hence it contains only a single reference `0`. `0` is an index into the `q:obj` attribute which contains a reference to the actual serialized object referring to `store`. (The exact mechanisms and syntax is an implementation detail that can change at any time.)
|
||||
|
||||
@@ -100,6 +88,7 @@ In our case `() => store.count++` only captures `store`, and hence it contains o
|
||||
JavaScript supports dynamic `import()`. At first glance, it may seem that the same can be achieved by `import()`, but there are a few differences worth mentioning.
|
||||
|
||||
Dynamic `import()`:
|
||||
|
||||
- Is relative to the file which contains it. This works great for `file-a.js` trying to load `file-b.js` as `import('./file-b.js')`. However, when the `./file-a.js` gets serialized into HTML then we lose its relative nature. It is the framework that reads the `./file-b.js` from HTML and performs the `import()`. This means that all imports now become relative to the framework, which is incorrect.
|
||||
- Requires that the developer writes `import('./file-a.js')`, which means the developer is in charge of deciding where the lazy-loaded boundaries are. This limits our ability of the tooling to move code around in an automated way.
|
||||
- Supports import of top-level functions only which don't capture the state. This is the biggest difference. Qwik allows the imported symbol to be a closure that carries all of its state with it.
|
||||
- Supports import of top-level functions only which don't capture the state. This is the biggest difference. Qwik allows the imported symbol to be a closure that carries all of its state with it.
|
||||
@@ -254,10 +254,12 @@ There are a few things to notice:
|
||||
You may want to know how Qwik knows which code to download based on the user interaction. You can explore this by examining the DOM in the DevTools. Let's zoom in on the checkmark HTML. You should see something like this:
|
||||
|
||||
```html
|
||||
<input q:obj="9"
|
||||
type="checkbox"
|
||||
onClickQrl="/src/components/item/h_item_item_onrender_input_onclick.js#Item_onRender_input_onclick[0]"
|
||||
class="toggle">
|
||||
<input
|
||||
q:obj="9"
|
||||
type="checkbox"
|
||||
onClickQrl="/src/components/item/h_item_item_onrender_input_onclick.js#Item_onRender_input_onclick[0]"
|
||||
class="toggle"
|
||||
/>
|
||||
```
|
||||
|
||||
There are a few things to notice:
|
||||
@@ -15,11 +15,7 @@ Let's start by looking at a simple `Counter` example.
|
||||
const Counter = component$(() => {
|
||||
const store = useStore({ count: 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={() => store.count++}>
|
||||
{store.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={() => store.count++}>{store.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -87,15 +83,11 @@ Let's look at our example again:
|
||||
const Counter = component$(() => {
|
||||
const store = useStore({ count: 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={() => store.count++}>
|
||||
{store.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={() => store.count++}>{store.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
Notice the presence of `$` in the code. `$` is a marker that tells the Optimizer that the function
|
||||
following it should be lazy-loaded. (For a detailed discussion see [$ and Optimizer Rules](./optimizer/rules.mdx).)
|
||||
The `$` is a single character that hints to the Optimizer and the developer to let them know
|
||||
Notice the presence of `$` in the code. `$` is a marker that tells the Optimizer that the function
|
||||
following it should be lazy-loaded. (For a detailed discussion see [$ and Optimizer Rules](./optimizer/rules.mdx).)
|
||||
The `$` is a single character that hints to the Optimizer and the developer to let them know
|
||||
that asynchronous lazy-loading occurs here.
|
||||
@@ -11,9 +11,7 @@ Let's look at a simple case:
|
||||
|
||||
```tsx
|
||||
const Greeter = component$(() => {
|
||||
return (
|
||||
<span>Hello World!</span>
|
||||
);
|
||||
return <span>Hello World!</span>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -44,9 +42,11 @@ const Greeter = component$((props: { name: string }) => {
|
||||
const salutation = 'Hello';
|
||||
|
||||
return (
|
||||
<span>{salutation} {props.name}!</span>
|
||||
<span>
|
||||
{salutation} {props.name}!
|
||||
</span>
|
||||
);
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
The naive way to extract functions will not work.
|
||||
@@ -15,11 +15,7 @@ Let's start by looking at a simple `Counter` example:
|
||||
const Counter = component$(() => {
|
||||
const store = useStore({ count: 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={() => store.count++}>
|
||||
{store.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={() => store.count++}>{store.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -44,9 +40,7 @@ export const Counter_onMount = () => {
|
||||
const Counter_onRender = () => {
|
||||
const [store] = useLexicalScope();
|
||||
return (
|
||||
<button onClickQrl={qrl('./chunk-c.js', 'Counter_onClick', [store])}>
|
||||
{store.count}
|
||||
</button>
|
||||
<button onClickQrl={qrl('./chunk-c.js', 'Counter_onClick', [store])}>{store.count}</button>
|
||||
);
|
||||
};
|
||||
```
|
||||
@@ -79,11 +79,7 @@ function somefn() {
|
||||
list.foreach((item) => {
|
||||
count++;
|
||||
const currentCount = count;
|
||||
someApi$(qrl('./chunk-a.js', '_1', [
|
||||
item,
|
||||
count,
|
||||
currentCount,
|
||||
]));
|
||||
someApi$(qrl('./chunk-a.js', '_1', [item, count, currentCount]));
|
||||
});
|
||||
}
|
||||
```
|
||||
@@ -10,10 +10,13 @@ Qwik is a new kind of web framework that can deliver instant loading web applica
|
||||
## Qwik is:
|
||||
|
||||
- **General-purpose**: Qwik can be used to build any type of web site or application
|
||||
- **Instant-on**: Unlike other frameworks, Qwik is [resumable](./resumable.mdx) which means Qwik applications require **0 hydration**. This allows Qwik apps to have instant-on interactivity, regardless of size or complexity
|
||||
- **Instant-on**: Unlike other frameworks, Qwik is [resumable](./resumable.mdx) which means Qwik applications require **0 hydration**. This allows Qwik apps to have instant-on interactivity, regardless of size or complexity
|
||||
- **Optimized for speed**: Qwik has unprecedented performance, offering sub-second full page loads even on mobile devices. Qwik achieves this by delivering pure HTML, and incrementally loading JS only as-needed.
|
||||
|
||||
<img alt="Qwik Diagram" src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fd33c7a95e98144f682ab67dd27d1f957?format=webp&width=2000" />
|
||||
<img
|
||||
alt="Qwik Diagram"
|
||||
src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fd33c7a95e98144f682ab67dd27d1f957?format=webp&width=2000"
|
||||
/>
|
||||
|
||||
## Does page speed really matter?
|
||||
|
||||
@@ -21,20 +24,9 @@ Put simply: slow sites deter visitors, costing businesses millions. Fast sites h
|
||||
|
||||
Some examples from [web.dev](https://web.dev):
|
||||
|
||||
| | |
|
||||
|--|--|
|
||||
| **Every 100ms faster → 1% more conversions** <br /> For Mobify, every 100ms decrease in homepage load speed worked out to a 1.11% increase in session-based conversion, yielding an average annual revenue increase of nearly $380,000. | **50% faster → 12% more sales** <br /> When AutoAnything reduced page load time by half, they saw a boost of 12% to 13% in sales.
|
||||
| **20% faster → 10% more conversions** <br /> Retailer Furniture Village audited their site speed and developed a plan to address the problems they found, leading to a 20% reduction in page load time and a 10% increase in conversion rate. | **40% faster → 15% more sign-ups** <br /> Pinterest reduced perceived wait times by 40% and this increased search engine traffic and sign-ups by 15%. |
|
||||
| **850ms faster → 7% more conversions** <br /> COOK reduced average page load time by 850 milliseconds which increased conversions by 7%, decreased bounce rates by 7%, and increased pages per session by 10%. | **1 seconds slowness → 10% less users** <br /> The BBC found they lost an additional 10% of users for every additional second their site took to load.
|
||||
| | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| | |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Every 100ms faster → 1% more conversions** <br /> For Mobify, every 100ms decrease in homepage load speed worked out to a 1.11% increase in session-based conversion, yielding an average annual revenue increase of nearly $380,000. | **50% faster → 12% more sales** <br /> When AutoAnything reduced page load time by half, they saw a boost of 12% to 13% in sales. |
|
||||
| **20% faster → 10% more conversions** <br /> Retailer Furniture Village audited their site speed and developed a plan to address the problems they found, leading to a 20% reduction in page load time and a 10% increase in conversion rate. | **40% faster → 15% more sign-ups** <br /> Pinterest reduced perceived wait times by 40% and this increased search engine traffic and sign-ups by 15%. |
|
||||
| **850ms faster → 7% more conversions** <br /> COOK reduced average page load time by 850 milliseconds which increased conversions by 7%, decreased bounce rates by 7%, and increased pages per session by 10%. | **1 seconds slowness → 10% less users** <br /> The BBC found they lost an additional 10% of users for every additional second their site took to load. |
|
||||
| | |
|
||||
@@ -29,10 +29,10 @@ Below you can find a simple HTML with Qwikloader and a button with associated be
|
||||
```html
|
||||
<html>
|
||||
<body q:base="/build/">
|
||||
<button onClickQrl="./myHandler.js#clickHandler">
|
||||
push me
|
||||
</button>
|
||||
<script>/* Qwikloader */</script>
|
||||
<button onClickQrl="./myHandler.js#clickHandler">push me</button>
|
||||
<script>
|
||||
/* Qwikloader */
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -34,11 +34,7 @@ Because of the above constraints, Qwik uses proxies to keep track of the reactiv
|
||||
const Counter = component$(() => {
|
||||
const store = useStore({ count: 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={store.count++}>
|
||||
{store.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={store.count++}>{store.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -58,12 +54,8 @@ const ComplexCounter = component$(() => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button onClick$={(store.visible = !store.visible)}>
|
||||
{store.visible ? 'hide' : 'show'}
|
||||
</button>
|
||||
<button onClick$={store.count++}>
|
||||
increment
|
||||
</button>
|
||||
<button onClick$={(store.visible = !store.visible)}>{store.visible ? 'hide' : 'show'}</button>
|
||||
<button onClick$={store.count++}>increment</button>
|
||||
{store.visible ? <span>{store.count}</span> : null}
|
||||
</>
|
||||
);
|
||||
@@ -114,7 +106,7 @@ const MyComp = component$(() => {
|
||||
const store = useStore({ person: null });
|
||||
const person = { first: 'John', last: 'Smith' };
|
||||
store.person = person; // `store.person auto wraps object into proxy`
|
||||
|
||||
|
||||
if (store.person !== person) {
|
||||
// The consequence of auto wrapping is that the object identity changes.
|
||||
console.log('store auto-wrapped person into a proxy');
|
||||
@@ -16,11 +16,7 @@ Simple counter example:
|
||||
const Counter = component$(() => {
|
||||
const store = useStore({ count: 0 });
|
||||
|
||||
return (
|
||||
<button onClick$={() => store.count++}>
|
||||
{store.count}
|
||||
</button>
|
||||
);
|
||||
return <button onClick$={() => store.count++}>{store.count}</button>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -28,9 +24,7 @@ Once rendered the HTML fragment may look something like this:
|
||||
|
||||
```html
|
||||
<div q:host>
|
||||
<button q:obj="123" onClickQrl="./chunk-a.js#Counter_button_click[0]">
|
||||
0
|
||||
</button>
|
||||
<button q:obj="123" onClickQrl="./chunk-a.js#Counter_button_click[0]">0</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
@@ -55,12 +49,8 @@ const Parent = component$(() => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button onClick$={(store.step *= -1)}>
|
||||
direction
|
||||
</button>
|
||||
<button onClick$={() => (store.count += store.step)}>
|
||||
{store.step}
|
||||
</button>
|
||||
<button onClick$={(store.step *= -1)}>direction</button>
|
||||
<button onClick$={() => (store.count += store.step)}>{store.step}</button>
|
||||
<Greeter name={'World_' + store.count} />
|
||||
</>
|
||||
);
|
||||
@@ -11,17 +11,18 @@ The short answer is that Qwik solves a problem that other frameworks can't solve
|
||||
## What is the problem?
|
||||
|
||||
Modern websites require vast amounts of JavaScript to become interactive. Too much JavaScript manifests itself in two problems:
|
||||
1. **Network bandwidth**: A large amount of code is shipped to the client, which may take a long time on slow networks.
|
||||
|
||||
1. **Network bandwidth**: A large amount of code is shipped to the client, which may take a long time on slow networks.
|
||||
2. **Startup time**: Once on the client, the code needs to be executed (as part of hydration) to get the site interactive.
|
||||
|
||||
As our applications get more complex with a higher fidelity of interactivity, the amount of code has steadily increased over the years with no sign of stopping. Simply put, our sites are getting more complex. An increase in site complexity, in turn, requires more code. All of this code negatively impacts site startup performance.
|
||||
|
||||
To make matters worse, JavaScript is single-threaded; therefore, our complex sites can't take advantage of modern multi-core CPUs.
|
||||
|
||||
|
||||
## Why is the problem worth solving?
|
||||
|
||||
Because there is a lot of evidence that says that site startup performance affects the bottom line. Slow sites:
|
||||
|
||||
- Frustrate users
|
||||
- Lower conversion rates
|
||||
- Decrease profits
|
||||
@@ -30,32 +31,32 @@ Put simply: slow sites deter visitors, costing businesses millions. Fast sites h
|
||||
|
||||
Some examples from [web.dev](https://web.dev):
|
||||
|
||||
| | |
|
||||
|--|--|
|
||||
| **Every 100ms faster → 1% more conversions** <br /> For Mobify, every 100ms decrease in homepage load speed worked out to a 1.11% increase in session-based conversion, yielding an average annual revenue increase of nearly $380,000. | **50% faster → 12% more sales** <br /> When AutoAnything reduced page load time by half, they saw a boost of 12% to 13% in sales.
|
||||
| **20% faster → 10% more conversions** <br /> Retailer Furniture Village audited their site speed and developed a plan to address the problems they found, leading to a 20% reduction in page load time and a 10% increase in conversion rate. | **40% faster → 15% more sign-ups** <br /> Pinterest reduced perceived wait times by 40% and this increased search engine traffic and sign-ups by 15%. |
|
||||
| **850ms faster → 7% more conversions** <br /> COOK reduced average page load time by 850 milliseconds which increased conversions by 7%, decreased bounce rates by 7%, and increased pages per session by 10%. | **1 seconds slowness → 10% less users** <br /> The BBC found they lost an additional 10% of users for every additional second their site took to load.
|
||||
| | |
|
||||
| | |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Every 100ms faster → 1% more conversions** <br /> For Mobify, every 100ms decrease in homepage load speed worked out to a 1.11% increase in session-based conversion, yielding an average annual revenue increase of nearly $380,000. | **50% faster → 12% more sales** <br /> When AutoAnything reduced page load time by half, they saw a boost of 12% to 13% in sales. |
|
||||
| **20% faster → 10% more conversions** <br /> Retailer Furniture Village audited their site speed and developed a plan to address the problems they found, leading to a 20% reduction in page load time and a 10% increase in conversion rate. | **40% faster → 15% more sign-ups** <br /> Pinterest reduced perceived wait times by 40% and this increased search engine traffic and sign-ups by 15%. |
|
||||
| **850ms faster → 7% more conversions** <br /> COOK reduced average page load time by 850 milliseconds which increased conversions by 7%, decreased bounce rates by 7%, and increased pages per session by 10%. | **1 seconds slowness → 10% less users** <br /> The BBC found they lost an additional 10% of users for every additional second their site took to load. |
|
||||
| | |
|
||||
|
||||
## How did we get here?
|
||||
|
||||
The solution to the above problem is both obvious and hard: Ship less JavaScript.
|
||||
The solution to the above problem is both obvious and hard: Ship less JavaScript.
|
||||
|
||||
It's obvious because we all agree that sites with less JavaScript would perform better.
|
||||
It's obvious because we all agree that sites with less JavaScript would perform better.
|
||||
|
||||
It is hard because our tools don't help us to get there. Almost all of our tools solve problems in a way that makes shipping less JavaScript hard. This is because most of our tools are designed to solve a specific problem without thinking about the amount of JavaScript they generate.
|
||||
It is hard because our tools don't help us to get there. Almost all of our tools solve problems in a way that makes shipping less JavaScript hard. This is because most of our tools are designed to solve a specific problem without thinking about the amount of JavaScript they generate.
|
||||
|
||||
Do you need to solve rendering, styling, animation, A/B testing, analytics, etc.? There is a tool for that. Just import or add a `<script>` tag, and these tools will solve your problems, but at the expense of making the initial bundle bigger.
|
||||
Do you need to solve rendering, styling, animation, A/B testing, analytics, etc.? There is a tool for that. Just import or add a `<script>` tag, and these tools will solve your problems, but at the expense of making the initial bundle bigger.
|
||||
|
||||
As an industry, we have failed to think about the implication of bundle size. Each tool solves a specific problem individually, but the size is not part of the equation. Size is the problem that emerges when you put all of the tools together, and by that point, there is very little the developer can do about it.
|
||||
|
||||
# Solution
|
||||
|
||||
Qwik is designed from the ground up to address the size problem. Small bundle size is its initial goal, and all other design decisions are subservient to that goal.
|
||||
Qwik is designed from the ground up to address the size problem. Small bundle size is its initial goal, and all other design decisions are subservient to that goal.
|
||||
|
||||
Qwik is not about creating less JavaScript. Qwik is about not having to ship all of that JavaScript to the client at once on application startup. Qwik is what you end up with when you take the idea of delay loading of JavaScript to the extreme.
|
||||
|
||||
Yes, Qwik requires a different way of thinking and designing your application, but the result is near zero initial JavaScript with progressive JavaScript download based on user interactions.
|
||||
Yes, Qwik requires a different way of thinking and designing your application, but the result is near zero initial JavaScript with progressive JavaScript download based on user interactions.
|
||||
|
||||
## Size should not be a developer problem
|
||||
|
||||
@@ -63,22 +64,23 @@ Today, size is the developers' problem. If you follow best practices for each of
|
||||
|
||||
Our industry best practices lead to large bundles, and the web is full of examples.
|
||||
|
||||
The mantra of Qwik is that bundle size should not be something that developers should think about. It should just naturally emerge as part of how the framework is designed.
|
||||
The mantra of Qwik is that bundle size should not be something that developers should think about. It should just naturally emerge as part of how the framework is designed.
|
||||
|
||||
Qwik is designed from the ground up to produce lots of lazy loadable boundaries. Tooling can break up your application into many lazy-loadable chunks, and the runtime can download them only when needed.
|
||||
|
||||
## What is Qwik
|
||||
|
||||
Qwik is a framework that, above all else, desires to have instant-on application. Qwik achieves this through:
|
||||
|
||||
1. **Philosophy**: Qwik's philosophy extends into API designed in such a way so that lazy loading is introduced into the codebase without undue burden on the developer.
|
||||
2. **Optimizer**: A Build system that can take advantage of the philosophy to produce a lot of entry points for your application (a large number of entry points allows you to break the application into many small chunks.)
|
||||
1. **runtime**: A runtime that understands the bundling strategy to deliver on the promise of instant-on applications (In many cases, the application can be interactive with near-zero JavaScript.)
|
||||
3. **runtime**: A runtime that understands the bundling strategy to deliver on the promise of instant-on applications (In many cases, the application can be interactive with near-zero JavaScript.)
|
||||
|
||||
## Why not fix existing frameworks/tools
|
||||
|
||||
In short, the lazy loading philosophy is at a low level and can not be retroactively added to the existing frameworks/tools without changing them fundamentally. Such fundamental change would be incompatible with the framework/tools and their respective ecosystems, rendering them useless.
|
||||
In short, the lazy loading philosophy is at a low level and can not be retroactively added to the existing frameworks/tools without changing them fundamentally. Such fundamental change would be incompatible with the framework/tools and their respective ecosystems, rendering them useless.
|
||||
|
||||
When a framework makes certain assumptions, such as that all rendering is synchronous, adding asynchronous lazy loading becomes pretty close to impossible. Or, if a framework recovers the listener location from templates, then download and execution of those templates is a must before the site can be interactive. These are just some of the more obvious examples, but in practice, there is a long tail of endless reasons why the current mental model does not fit the requirements of resumability.
|
||||
When a framework makes certain assumptions, such as that all rendering is synchronous, adding asynchronous lazy loading becomes pretty close to impossible. Or, if a framework recovers the listener location from templates, then download and execution of those templates is a must before the site can be interactive. These are just some of the more obvious examples, but in practice, there is a long tail of endless reasons why the current mental model does not fit the requirements of resumability.
|
||||
|
||||
The above also means that it is not feasible for existing frameworks to add resumability as a feature. Existing frameworks will never be able to do what Qwik can (without breaking backward compatibility).
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { component$ } from '@builder.io/qwik';
|
||||
|
||||
export const Main = component$(() => {
|
||||
return (
|
||||
<div>
|
||||
</div>
|
||||
);
|
||||
return <div></div>;
|
||||
});
|
||||
@@ -3,4 +3,4 @@ title: Basics - Qwik Tutorial
|
||||
layout: tutorial
|
||||
---
|
||||
|
||||
Welcome to the Qwik tutorial.
|
||||
Welcome to the Qwik tutorial.
|
||||
@@ -1,8 +1,5 @@
|
||||
import { component$ } from '@builder.io/qwik';
|
||||
|
||||
export const Main = component$(() => {
|
||||
return (
|
||||
<div>
|
||||
</div>
|
||||
);
|
||||
return <div></div>;
|
||||
});
|
||||
@@ -3,4 +3,4 @@ title: Lazy Loading - Qwik Tutorial
|
||||
layout: tutorial
|
||||
---
|
||||
|
||||
Lazy loading.
|
||||
Lazy loading.
|
||||
@@ -1,8 +1,5 @@
|
||||
import { component$ } from '@builder.io/qwik';
|
||||
|
||||
export const Main = component$(() => {
|
||||
return (
|
||||
<div>
|
||||
</div>
|
||||
);
|
||||
return <div></div>;
|
||||
});
|
||||
@@ -3,4 +3,4 @@ title: Reactivity Assignments - Qwik Tutorial
|
||||
layout: tutorial
|
||||
---
|
||||
|
||||
Reactivity Assignments.
|
||||
Reactivity Assignments.
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
@@ -1,4 +1,4 @@
|
||||
import { usePage, usePageIndex, PageIndex } from '@builder.io/qwest';
|
||||
import { usePage, usePageIndex, PageIndex } from '@builder.io/qwik-city';
|
||||
import { component$, Host, useHostElement, useScopedStyles$ } from '@builder.io/qwik';
|
||||
import styles from './content-nav.css?inline';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { usePage } from '@builder.io/qwest';
|
||||
import { usePage } from '@builder.io/qwik-city';
|
||||
import { component$, Host, $, useHostElement, useScopedStyles$ } from '@builder.io/qwik';
|
||||
import { ChatIcon } from '../svgs/chat-icon';
|
||||
import { EditIcon } from '../svgs/edit-icon';
|
||||
@@ -1,7 +1,7 @@
|
||||
import { component$, useHostElement } from '@builder.io/qwik';
|
||||
import { Builder } from '../../layouts/builder/builder';
|
||||
import { setHeadLinks, setHeadMeta, usePage } from '@builder.io/qwest';
|
||||
import { SiteStore } from '../app/app';
|
||||
import { setHeadLinks, setHeadMeta, usePage } from '@builder.io/qwik-city';
|
||||
import type { SiteStore } from '../app/app';
|
||||
|
||||
interface PageProps {
|
||||
store: SiteStore;
|
||||
@@ -1,10 +1,10 @@
|
||||
import { component$, Host, useHostElement, useScopedStyles$ } from '@builder.io/qwik';
|
||||
import { usePage, usePageIndex } from '@builder.io/qwest';
|
||||
import { usePage, usePageIndex } from '@builder.io/qwik-city';
|
||||
import type { SiteStore } from '../app/app';
|
||||
import { CloseIcon } from '../svgs/close-icon';
|
||||
import styles from './sidebar.css?inline';
|
||||
|
||||
interface SideBarProps {
|
||||
export interface SideBarProps {
|
||||
store: SiteStore;
|
||||
}
|
||||
|
||||