├── .github └── workflows │ └── main.yml ├── .gitignore ├── README.md ├── app ├── css │ └── index.css ├── index.html └── js │ └── index.js ├── lighthouserc.json ├── package-lock.json ├── package.json ├── postcss.config.js └── rollup.config.mjs /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Lighthouse 2 | on: [push] 3 | jobs: 4 | lhci: 5 | name: CI 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v2 9 | - name: Build 10 | run: | 11 | npm install 12 | npm run build 13 | - name: Test dist/ 14 | uses: treosh/lighthouse-ci-action@v2 15 | env: 16 | LHCI_GITHUB_APP_TOKEN: ${{secrets.LHCI_GITHUB_APP_TOKEN}} 17 | with: 18 | configPath: './lighthouserc.json' 19 | temporaryPublicStorage: true 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | app/bundle.css 4 | app/bundle.js 5 | .DS_Store 6 | .cache -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Netlify Status](https://api.netlify.com/api/v1/badges/59a03ed4-bf70-4441-b65c-200bcd61c013/deploy-status)](https://app.netlify.com/sites/shortstax/deploys) 2 | 3 | ### CSS 4 | [PostCSS](https://postcss.org) to **bundle**, **import from NPM, local or remote URLs**, plus [postcss-preset-env](https://preset-env.cssdb.org/) for **latest CSS features**. 5 | 6 | ### JS 7 | [Rollup](https://rollupjs.org) to **bundle**, **treeshake**, **import from NPM, local or remote URLs**, **import processed CSS**, plus [babel-preset-env](https://babeljs.io/docs/en/babel-preset-env) for **latest JS features**. 8 | 9 | ### Servers 10 | [Browsersync](https://www.browsersync.io) with all the goodies for local dev: **live reload**, **hot swap CSS**, **scroll syncing**, **remote debugging**, [etc](https://www.browsersync.io). Prod server is just a static server. 11 | 12 |
13 | 14 | > Watch me break it down on [YouTube!](https://links.argyle.ink/shortstack) 15 | 16 |

17 | 18 | ## Getting Started 19 | [use this as a Github template](https://github.com/argyleink/shortstack/generate) 20 | 21 | OR 22 | 23 | #### Clone Shortstack into a new folder 24 | 1. `mkdir new-project-name && cd $_` 25 | 1. `git clone --depth=1 https://github.com/argyleink/shortstack.git . && rm -rf ./.git` 26 | 27 | OR (essentially the same thing with npx+degit) 28 | 29 | 1. `npx degit argyleink/shortstack#main` 30 | 31 | #### Install tools and spin it up 32 | 1. `npm i` 33 | 1. `npm start` 34 | 35 |

36 | 37 | ## Development 38 | Running `npm start` runs Browsersync, Rollup and Postcss concurrently, watching changes to your files in `./app` and refreshes connected browsers. 39 | 40 | ## Production 41 | Running `npm run build` compiles and minifies your code in `app` and outputs the optimised result to a folder called `dist` that's ready for static hosting. 42 | 43 | Running `npm run production` will build your project and start a server at `dist`. 44 | -------------------------------------------------------------------------------- /app/css/index.css: -------------------------------------------------------------------------------- 1 | /* 2 | (bundle from remote urls) 3 | @import '//css-from-url'; 4 | 5 | (bundle from npm) 6 | @import 'css-from-npm'; 7 | 8 | (bundle from local) 9 | @import 'localfile.css' 10 | 11 | (PresetENV) 12 | CSS powers @ https://preset-env.cssdb.org/features 13 | */ 14 | 15 | :root { 16 | --surface: lch(10 0 0); 17 | --text: lch(80 0 0); 18 | --brand: lch(64 40 347); 19 | 20 | @media (prefers-color-scheme: light) { 21 | --surface: lch(98 0 0); 22 | --text: lch(30 0 0); 23 | --brand: lch(65 64 350); 24 | 25 | @media (dynamic-range: high) { 26 | --brand: color(display-p3 1 0 1); 27 | } 28 | } 29 | } 30 | 31 | html { 32 | block-size: 100%; 33 | inline-size: 100%; 34 | } 35 | 36 | body { 37 | min-block-size: 100%; 38 | min-inline-size: 100%; 39 | box-sizing: border-box; 40 | 41 | display: grid; 42 | place-content: center; 43 | gap: 2ch; 44 | 45 | background: var(--surface); 46 | color: var(--text); 47 | font-family: system-ui, sans-serif; 48 | } 49 | 50 | @media (orientation: landscape) { 51 | body { 52 | grid-auto-flow: column; 53 | } 54 | } 55 | 56 | body,p,ul,dl,dd,dt,figure, 57 | h1,h2,h3,h4,h5,h6,small { 58 | margin: 0; 59 | } 60 | 61 | a { 62 | color: color(display-p3 0 .5 1); 63 | 64 | &:visited { 65 | color: color(display-p3 .5 0 1); 66 | } 67 | } 68 | 69 | h1,h2,h3,h4,h5,h6 { 70 | line-height: 1.5; 71 | max-inline-size: 25ch; 72 | } 73 | 74 | p { 75 | line-height: 2; 76 | font-size: 1.25rem; 77 | font-weight: 300; 78 | max-inline-size: 45ch; 79 | } 80 | 81 | ::selection { 82 | background-color: var(--brand); 83 | } 84 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shortstack 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

ready.

20 | v1.2.0 21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/js/index.js: -------------------------------------------------------------------------------- 1 | // (bundle from remote urls) 2 | // import Whatever from 'https://unpkg.com/whatever' 3 | 4 | // (bundle from npm) 5 | // import Whatever from 'whatever' 6 | // import $ from 'blingblingjs' 7 | 8 | // (bundle from local) 9 | // import whatever from './whatever.js' 10 | 11 | // postCSS processed css-4-js 12 | // (file as string) 13 | // import { default as index_css } from './css/index.css' 14 | 15 | console?.log('💀') -------------------------------------------------------------------------------- /lighthouserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "ci": { 3 | "collect": { 4 | "staticDistDir": "./dist" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shortstack", 3 | "version": "1.2.0", 4 | "author": "Adam Argyle", 5 | "description": "rollup & postcss bundler starter", 6 | "license": "ISC", 7 | "main": "index.js", 8 | "browserslist": [ 9 | "defaults" 10 | ], 11 | "scripts": { 12 | "dev:js": "rollup -c -w", 13 | "dev:css": "postcss app/css/index.css -o app/bundle.css -w", 14 | "dev:server": "browser-sync app --files \"app/**/*, !app/css/**, !app/js/**\" --no-open --no-notify", 15 | "prod:server": "browser-sync dist --no-open --no-notify --no-ghost-mode", 16 | "build:pre:js": "rollup -c --environment NODE_ENV:production", 17 | "build:pre:css": "postcss app/css/index.css -o dist/bundle.css --env production", 18 | "build:post:copy": "cp app/index.html dist/index.html", 19 | "build": "rimraf dist && concurrently npm:build:pre:* && concurrently npm:build:post:*", 20 | "start": "concurrently --kill-others npm:dev:*", 21 | "production": "npm run build && npm run prod:server" 22 | }, 23 | "devDependencies": { 24 | "@ampproject/rollup-plugin-closure-compiler": "0.27.0", 25 | "@babel/core": "^7.20.2", 26 | "@babel/preset-env": "^7.20.2", 27 | "@rollup/plugin-babel": "^6.0.2", 28 | "@rollup/plugin-node-resolve": "^15.0.1", 29 | "browser-sync": "^2.27.10", 30 | "concurrently": "^7.5.0", 31 | "cssnano": "^5.1.14", 32 | "import-http": "^0.3.1", 33 | "postcss": "^8.4.19", 34 | "postcss-cli": "^10.0.0", 35 | "postcss-import": "^15.0.0", 36 | "postcss-import-url": "^7.0.0", 37 | "postcss-loader": "^7.0.1", 38 | "postcss-preset-env": "^7.8.2", 39 | "rimraf": "^3.0.2", 40 | "rollup": "^3.3.0", 41 | "rollup-plugin-postcss": "^4.0.2", 42 | "rollup-plugin-terser": "^7.0.2" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const postcssPresetEnv = require('postcss-preset-env') 2 | const postcssImport = require('postcss-import') 3 | const importUrl = require('postcss-import-url') 4 | const cssnano = require('cssnano') 5 | 6 | const dev = { 7 | plugins: [ 8 | importUrl(), 9 | postcssImport({ 10 | path: 'app/css', 11 | }), 12 | postcssPresetEnv({ 13 | stage: 0, 14 | features: { 15 | 'logical-properties-and-values': false, 16 | 'prefers-color-scheme-query': false, 17 | 'gap-properties': false, 18 | } 19 | }), 20 | ] 21 | } 22 | 23 | const prod = { 24 | plugins: [ 25 | importUrl(), 26 | postcssImport({ 27 | path: 'app/css', 28 | }), 29 | postcssPresetEnv({ 30 | stage: 0, 31 | features: { 32 | 'logical-properties-and-values': false, 33 | 'prefers-color-scheme-query': false, 34 | 'gap-properties': false, 35 | } 36 | }), 37 | cssnano({ 38 | preset: 'default' 39 | }), 40 | ] 41 | } 42 | 43 | module.exports = process.env.NODE_ENV === 'production' 44 | ? prod 45 | : dev 46 | -------------------------------------------------------------------------------- /rollup.config.mjs: -------------------------------------------------------------------------------- 1 | import resolve from '@rollup/plugin-node-resolve' 2 | import postcss from 'rollup-plugin-postcss' 3 | import { terser } from 'rollup-plugin-terser' 4 | import compiler from '@ampproject/rollup-plugin-closure-compiler' 5 | import { default as importHTTP } from 'import-http/rollup.js' 6 | import babel from '@rollup/plugin-babel' 7 | 8 | const dev = { 9 | input: 'app/js/index.js', 10 | output: { 11 | file: 'app/bundle.js', 12 | format: 'esm', 13 | sourcemap: 'inline', 14 | }, 15 | plugins: [ 16 | resolve(), 17 | importHTTP(), 18 | postcss({ 19 | inject: false, 20 | }), 21 | babel({ 22 | exclude: 'node_modules/**', 23 | "presets": [ 24 | ["@babel/env"] 25 | ] 26 | }), 27 | ], 28 | watch: { 29 | exclude: ['node_modules/**'], 30 | } 31 | } 32 | 33 | const prod = { 34 | input: 'app/js/index.js', 35 | output: { 36 | file: 'dist/bundle.js', 37 | format: 'esm', 38 | sourcemap: true, 39 | }, 40 | plugins: [ 41 | resolve(), 42 | importHTTP(), 43 | postcss({ 44 | extract: true, 45 | minimize: { preset: 'default' }, 46 | }), 47 | babel({ 48 | exclude: 'node_modules/**', 49 | "presets": [ 50 | ["@babel/env"] 51 | ] 52 | }), 53 | compiler(), 54 | terser(), 55 | ] 56 | } 57 | 58 | export default process.env.NODE_ENV === 'production' 59 | ? prod 60 | : dev 61 | 62 | --------------------------------------------------------------------------------