diff --git a/.eslintrc b/.eslintrc index 13eab9b48..2cbb43d4b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -36,13 +36,6 @@ } }, "rules": { - "quotes": [ - "error", - "single", - { - "allowTemplateLiterals": true - } - ], "react/jsx-uses-react": "off", "react/react-in-jsx-scope": "off" }, diff --git a/.github/workflows/create-spectacle.yml b/.github/workflows/create-spectacle.yml new file mode 100644 index 000000000..a1d40be12 --- /dev/null +++ b/.github/workflows/create-spectacle.yml @@ -0,0 +1,69 @@ +name: create-spectacle + +on: + push: + branches: + - main + paths: + - "packages/create-spectacle/**" + pull_request: + branches: + - main + paths: + - "packages/create-spectacle/**" + +jobs: + build: + name: Create, build, and install + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18.x] + create-type: ['jsx', 'tsx', 'onepage'] + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + + # Wireit cache + - uses: google/wireit@setup-github-actions-caching/v1 + + - uses: pnpm/action-setup@v2.2.2 + with: + version: 7 + + - name: Get pnpm store directory + id: pnpm-cache + run: echo "::set-output name=pnpm_cache_dir::$(pnpm store path)" + + - name: Setup pnpm cache + uses: actions/cache@v3 + with: + path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('./pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install + + - name: Build create-spectacle + run: pnpm run --filter ./packages/create-spectacle build + + # Create, build, isntall a full example. + # Then, start a background dev server. + - name: Create example - ${{ matrix.create-type }} + working-directory: ./packages/create-spectacle + run: | + pnpm run examples:${{ matrix.create-type }}:create && \ + pnpm run examples:${{ matrix.create-type }}:install && \ + pnpm run examples:${{ matrix.create-type }}:build && \ + pnpm run examples:${{ matrix.create-type }}:start & + + # Wait until the dev server is full up and running and then test. + - name: Test example - ${{ matrix.create-type }} + working-directory: ./packages/create-spectacle + run: | + pnpm exec wait-on http-get://localhost:3000 && \ + pnpm run examples:test diff --git a/.gitignore b/.gitignore index 717611e50..d3cc3d0e3 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,8 @@ dist lib es bin +.puppeteer +.examples # Pack-ing artifacts packages/**/package diff --git a/.prettierignore b/.prettierignore index d0f5e8009..68cf25d9a 100644 --- a/.prettierignore +++ b/.prettierignore @@ -11,6 +11,9 @@ build .nova .vscode .wireit +.examples +.changeset/*.md # Allow us to manually format this. examples/md/slides.md +examples/one-page/index.html diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b8ba70ef7..b56467ca4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -121,6 +121,57 @@ $ yarn clean:cache:wireit # wireit task cache $ yarn clean:cache:modules # caches in node_modules (prettier, etc.) ``` +### Checking `create-spectacle` + +We have slower checks for the outputs created by our `create-spectacle` package that are run in CI, but you generally won't need to run unless you are developing that package. + +First, you can install Chromium to use in `puppeteer` or use a local Chrome instance. We only presently have Mac instructions and will get to Windows/Linux support when we get demand. You only need to do the following step once. + +```sh +# Option 1 -- Do nothing! If you have the Mac Chrome app, you can skip this step! +# Option 2 -- Install chromium +# Option 2.a -- Normal binary +$ pnpm puppeteer:install +# Option 2.b -- If you are on an M1/2 Mac, do this instead: +$ PUPPETEER_EXPERIMENTAL_CHROMIUM_MAC_ARM=true pnpm puppeteer:install +``` + +After that, you'll want to either build or watch the `create-spectacle` files: + +```sh +$ pnpm run --filter ./packages/create-spectacle build +$ pnpm run --filter ./packages/create-spectacle build --watch +``` + +From there, here are sample collections of commands to create new example applications from scratch with full installation and ending with firing up a dev server: + +```sh +# JavaScript +$ pnpm run --filter ./packages/create-spectacle examples:jsx:clean && \ + pnpm run --filter ./packages/create-spectacle examples:jsx:create && \ + pnpm run --filter ./packages/create-spectacle examples:jsx:install && \ + pnpm run --filter ./packages/create-spectacle examples:jsx:build && \ + pnpm run --filter ./packages/create-spectacle examples:jsx:start + +# TypeScript +$ pnpm run --filter ./packages/create-spectacle examples:tsx:clean && \ + pnpm run --filter ./packages/create-spectacle examples:tsx:create && \ + pnpm run --filter ./packages/create-spectacle examples:tsx:install && \ + pnpm run --filter ./packages/create-spectacle examples:tsx:build && \ + pnpm run --filter ./packages/create-spectacle examples:tsx:start + +# One Page (HTML-only, no build step) +$ pnpm run --filter ./packages/create-spectacle examples:onepage:clean && \ + pnpm run --filter ./packages/create-spectacle examples:onepage:create && \ + pnpm run --filter ./packages/create-spectacle examples:onepage:start +``` + +The dev server in each of these examples runs on port 3000 by default, and you can run a simple Puppeteer test against that port with the following: + +```sh +$ pnpm run --filter ./packages/create-spectacle examples:test +``` + ### Before submitting a PR Thanks for taking the time to help us make Spectacle even better! Before you go ahead and submit a PR, make sure that you have done the following: diff --git a/examples/js/index.html b/examples/js/index.html index 428d8fee2..f02666f1f 100644 --- a/examples/js/index.html +++ b/examples/js/index.html @@ -1,10 +1,13 @@ - + <%= htmlWebpackPlugin.options.title %> - +
diff --git a/examples/js/package.json b/examples/js/package.json index bc08bca05..5c7ab396f 100644 --- a/examples/js/package.json +++ b/examples/js/package.json @@ -56,11 +56,11 @@ ] }, "prettier": { - "command": "nps prettier:pkg", + "command": "nps prettier:pkg -- -- \"*\"", "files": [ "../../.prettierignore", "../../.prettierrc", - "*.{js,jsx,ts,tsx}" + "*.{js,html}" ], "output": [], "packageLocks": [ @@ -68,11 +68,11 @@ ] }, "prettier:fix": { - "command": "pnpm run prettier || nps prettier:pkg:fix", + "command": "pnpm run prettier || nps prettier:pkg:fix -- -- \"*\"", "files": [ "../../.prettierignore", "../../.prettierrc", - "*.{js,jsx,ts,tsx}" + "*.{js,html}" ], "output": [], "packageLocks": [ diff --git a/examples/md/index.html b/examples/md/index.html index 428d8fee2..f02666f1f 100644 --- a/examples/md/index.html +++ b/examples/md/index.html @@ -1,10 +1,13 @@ - + <%= htmlWebpackPlugin.options.title %> - +
diff --git a/examples/md/package.json b/examples/md/package.json index 9ec4a450c..cdce404dc 100644 --- a/examples/md/package.json +++ b/examples/md/package.json @@ -56,11 +56,11 @@ ] }, "prettier": { - "command": "nps prettier:pkg", + "command": "nps prettier:pkg -- -- \"*\"", "files": [ "../../.prettierignore", "../../.prettierrc", - "*.{js,jsx,ts,tsx}" + "*.{js,html}" ], "output": [], "packageLocks": [ @@ -68,11 +68,11 @@ ] }, "prettier:fix": { - "command": "pnpm run prettier || nps prettier:pkg:fix", + "command": "pnpm run prettier || nps prettier:pkg:fix -- -- \"*\"", "files": [ "../../.prettierignore", "../../.prettierrc", - "*.{js,jsx,ts,tsx}" + "*.{js,html}" ], "output": [], "packageLocks": [ diff --git a/examples/one-page/package.json b/examples/one-page/package.json index e399f58a9..e58a1f59d 100644 --- a/examples/one-page/package.json +++ b/examples/one-page/package.json @@ -52,10 +52,11 @@ ] }, "prettier": { - "command": "nps prettier:pkg", + "command": "nps prettier:pkg -- -- \"*\" scripts", "files": [ "../../.prettierignore", "../../.prettierrc", + "*.html", "scripts" ], "output": [], @@ -64,10 +65,11 @@ ] }, "prettier:fix": { - "command": "pnpm run prettier || nps prettier:pkg:fix", + "command": "pnpm run prettier || nps prettier:pkg:fix -- -- \"*\" scripts", "files": [ "../../.prettierignore", "../../.prettierrc", + "*.html", "scripts" ], "output": [], diff --git a/examples/typescript/index.html b/examples/typescript/index.html index 428d8fee2..f02666f1f 100644 --- a/examples/typescript/index.html +++ b/examples/typescript/index.html @@ -1,10 +1,13 @@ - + <%= htmlWebpackPlugin.options.title %> - +
diff --git a/examples/typescript/package.json b/examples/typescript/package.json index e8d211c7a..4ceb93a51 100644 --- a/examples/typescript/package.json +++ b/examples/typescript/package.json @@ -73,11 +73,11 @@ ] }, "prettier": { - "command": "nps prettier:pkg", + "command": "nps prettier:pkg -- -- \"*\"", "files": [ "../../.prettierignore", "../../.prettierrc", - "*.{js,jsx,ts,tsx}" + "*.{js,jsx,ts,tsx,html}" ], "output": [], "packageLocks": [ @@ -85,11 +85,11 @@ ] }, "prettier:fix": { - "command": "pnpm run prettier || nps prettier:pkg:fix", + "command": "pnpm run prettier || nps prettier:pkg:fix -- -- \"*\"", "files": [ "../../.prettierignore", "../../.prettierrc", - "*.{js,jsx,ts,tsx}" + "*.{js,jsx,ts,tsx,html}" ], "output": [], "packageLocks": [ diff --git a/package-scripts.js b/package-scripts.js index 9b0d470ea..5e89af116 100644 --- a/package-scripts.js +++ b/package-scripts.js @@ -30,20 +30,21 @@ module.exports = { // - Webpack webpack: 'webpack', + // Test + jest: 'jest', + // Quality. // - Format - 'prettier:base': - 'prettier --list-different "./**/*.{js,jsx,json,ts,tsx,css,md}"', - 'prettier:base:fix': - 'prettier --write "./**/*.{js,jsx,json,ts,tsx,css,md}"', + 'prettier:base': 'prettier --list-different', + 'prettier:base:fix': 'prettier --write', 'prettier:pkg': - 'nps "prettier:base --config ../../.prettierrc --ignore-path ../../.prettierignore"', + 'nps prettier:base -- -- --config ../../.prettierrc --ignore-path ../../.prettierignore', 'prettier:pkg:fix': - 'nps "prettier:base:fix --config ../../.prettierrc --ignore-path ../../.prettierignore"', + 'nps prettier:base:fix -- -- --config ../../.prettierrc --ignore-path ../../.prettierignore', // - Lint 'lint:base': 'eslint --cache --color', - 'lint:pkg': 'nps "lint:base src"', - 'lint:pkg:fix': 'nps "lint:base --fix src"' + 'lint:pkg': 'nps lint:base -- -- src', + 'lint:pkg:fix': 'nps lint:base -- -- --fix src' } }; diff --git a/package.json b/package.json index f34e616a9..07cd425ec 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,10 @@ "@babel/preset-typescript": "^7.16.0", "@changesets/cli": "^2.23.1", "@svitejs/changesets-changelog-github-compact": "^0.1.1", - "@types/jest": "^27.0.2", + "@testing-library/jest-dom": "^5.16.4", + "@testing-library/react": "^13.3.0", + "@types/jest": "^27.5.2", + "@types/testing-library__jest-dom": "^5.14.5", "@typescript-eslint/eslint-plugin": "^5.4.0", "@typescript-eslint/parser": "^5.4.0", "babel-eslint": "^10.1.0", @@ -23,16 +26,29 @@ "eslint-plugin-react": "^7.27.0", "eslint-plugin-react-hooks": "^4.3.0", "html-webpack-plugin": "^5.5.0", + "jest": "^28.1.3", + "jest-environment-jsdom": "^28.1.3", + "jest-puppeteer": "^6.1.1", + "mkdirp": "^1.0.4", "nps": "^5.10.0", "prettier": "^2.4.1", + "puppeteer": "^16.0.0", "raw-loader": "^4.0.0", "rimraf": "^3.0.0", + "serve": "^14.0.1", + "ts-jest": "^28.0.7", "typescript": "^4.7.4", + "wait-on": "^6.0.1", "webpack": "^5.68.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.7.4", "wireit": "^0.7.1" }, + "pnpm": { + "neverBuiltDependencies": [ + "puppeteer" + ] + }, "scripts": { "version": "pnpm changeset version && pnpm install --no-frozen-lockfile", "changeset": "changeset", @@ -66,7 +82,8 @@ "prettier:root:fix": "wireit", "prettier:pkgs": "wireit", "prettier:pkgs:fix": "wireit", - "test": "wireit" + "test": "wireit", + "puppeteer:install": "rimraf .puppeteer && cross-env PUPPETEER_DOWNLOAD_PATH=.puppeteer node ./node_modules/puppeteer/install.js" }, "wireit": { "clean:cache": { @@ -177,11 +194,11 @@ ] }, "prettier:root": { - "command": "nps prettier:base", + "command": "nps prettier:base -- -- \"*.{js,json,md}\"", "files": [ ".prettierrc", ".prettierignore", - "*.{js,jsx,json,ts,tsx,css,md}", + "*.{js,json,md}", "!**/node_modules/**" ], "output": [], @@ -190,11 +207,11 @@ ] }, "prettier:root:fix": { - "command": "pnpm run prettier:root || nps prettier:base:fix", + "command": "pnpm run prettier:root || nps prettier:base:fix -- -- \"*.{js,json,md}\"", "files": [ ".prettierrc", ".prettierignore", - "*.{js,jsx,json,ts,tsx,css,md}", + "*.{js,json,md}", "!**/node_modules/**" ], "output": [], diff --git a/packages/create-spectacle/jest.config.js b/packages/create-spectacle/jest.config.js new file mode 100644 index 000000000..37f3f09d3 --- /dev/null +++ b/packages/create-spectacle/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + preset: 'ts-jest/presets/js-with-ts' +}; diff --git a/packages/create-spectacle/package.json b/packages/create-spectacle/package.json index 019246e58..2326bd76f 100644 --- a/packages/create-spectacle/package.json +++ b/packages/create-spectacle/package.json @@ -35,7 +35,24 @@ "lint": "wireit", "lint:fix": "wireit", "prettier": "wireit", - "prettier:fix": "wireit" + "prettier:fix": "wireit", + "examples:clean": "rimraf .examples", + "examples:test": "nps jest", + "examples:jsx:clean": "rimraf .examples/jsx", + "examples:jsx:create": "mkdirp .examples && cd .examples && node ../bin/cli.js -t jsx -n jsx", + "examples:jsx:install": "cd .examples/jsx && npm install", + "examples:jsx:build": "cd .examples/jsx && npm run build", + "examples:jsx:start": "cd .examples/jsx && npm start", + "examples:tsx:clean": "rimraf .examples/tsx", + "examples:tsx:create": "mkdirp .examples && cd .examples && node ../bin/cli.js -t tsx -n tsx", + "examples:tsx:install": "cd .examples/tsx && npm install", + "examples:tsx:build": "cd .examples/tsx && npm run build", + "examples:tsx:start": "cd .examples/tsx && npm start", + "examples:onepage:clean": "rimraf .examples/onepage", + "examples:onepage:create": "mkdirp .examples/onepage && cd .examples/onepage && node ../../bin/cli.js -t onepage -n index", + "examples:onepage:install": "echo unused", + "examples:onepage:build": "echo unused", + "examples:onepage:start": "pnpm exec serve .examples/onepage" }, "wireit": { "build": { @@ -53,11 +70,12 @@ ] }, "types:check": { - "command": "nps types:check", + "command": "nps types:check -- -- --p tsconfig.all.json", "files": [ "src/**/*.{ts,tsx}", - "../../tsconfig.json", - "tsconfig.json" + "test/**/*.{ts,tsx}", + "tsconfig.json", + "tsconfig.all.json" ], "dependencies": [], "output": [], @@ -66,12 +84,13 @@ ] }, "lint": { - "command": "nps lint:pkg", + "command": "nps lint:pkg -- -- test", "files": [ "../../.eslintignore", "../../.eslintrc", "*.js", - "src/**" + "src/**", + "test/**" ], "output": [], "packageLocks": [ @@ -79,12 +98,13 @@ ] }, "lint:fix": { - "command": "pnpm run lint || nps lint:pkg:fix", + "command": "pnpm run lint || nps lint:pkg:fix -- -- test", "files": [ "../../.eslintignore", "../../.eslintrc", "*.js", - "src/**" + "src/**", + "test/**" ], "output": [], "packageLocks": [ @@ -92,12 +112,13 @@ ] }, "prettier": { - "command": "nps prettier:pkg", + "command": "nps prettier:pkg -- -- src test", "files": [ "../../.prettierignore", "../../.prettierrc", "*.js", - "src/**" + "src/**", + "test/**" ], "output": [], "packageLocks": [ @@ -105,12 +126,13 @@ ] }, "prettier:fix": { - "command": "pnpm run prettier || nps prettier:pkg:fix", + "command": "pnpm run prettier || nps prettier:pkg:fix -- -- src test", "files": [ "../../.prettierignore", "../../.prettierrc", "*.js", - "src/**" + "src/**", + "test/**" ], "output": [], "packageLocks": [ diff --git a/packages/create-spectacle/src/templates/one-page.ts b/packages/create-spectacle/src/templates/one-page.ts index 23add9268..2f04aeb83 100644 --- a/packages/create-spectacle/src/templates/one-page.ts +++ b/packages/create-spectacle/src/templates/one-page.ts @@ -24,6 +24,7 @@ export const onePageTemplate = ({ name, lang }: OnePageTemplateOptions) => `