From 99d215c1d51d93d6ab624875133850a4a70b0ee2 Mon Sep 17 00:00:00 2001 From: Drew Powers Date: Wed, 19 May 2021 18:57:38 -0600 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20cache=20.css=20files=20for=20Ta?= =?UTF-8?q?ilwind=20projects?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves #3041, #3246 --- docs/guides/tailwind-css.md | 6 ++- docs/reference/configuration.md | 79 +++++++++++++++++----------- examples/tailwind/README.md | 10 ++++ examples/tailwind/package.json | 17 ++++++ examples/tailwind/postcss.config.js | 6 +++ examples/tailwind/public/global.css | 3 ++ examples/tailwind/public/index.html | 31 +++++++++++ examples/tailwind/snowpack.config.js | 11 ++++ examples/tailwind/tailwind.config.js | 5 ++ snowpack/src/commands/dev.ts | 7 ++- snowpack/src/config.ts | 1 + snowpack/src/types.ts | 1 + 12 files changed, 143 insertions(+), 34 deletions(-) create mode 100644 examples/tailwind/README.md create mode 100644 examples/tailwind/package.json create mode 100644 examples/tailwind/postcss.config.js create mode 100644 examples/tailwind/public/global.css create mode 100644 examples/tailwind/public/index.html create mode 100644 examples/tailwind/snowpack.config.js create mode 100644 examples/tailwind/tailwind.config.js diff --git a/docs/guides/tailwind-css.md b/docs/guides/tailwind-css.md index 4e5c94fe19..ecce89203b 100644 --- a/docs/guides/tailwind-css.md +++ b/docs/guides/tailwind-css.md @@ -49,7 +49,7 @@ module.exports = { _Note: be sure to set `purge: []` correctly for your project structure_ -Also, you’ll need to add the Snowpack PostCSS plugin to your Snowpack config, if you haven‘t already: +Also, you’ll need to add the Snowpack PostCSS plugin to your Snowpack config, and set the [Tailwind config option][config-tailwind], if you haven‘t already: ```diff // snowpack.config.js @@ -59,6 +59,9 @@ Also, you’ll need to add the Snowpack PostCSS plugin to your Snowpack config, src: '/_dist', public: '/', }, ++ devOptions: { ++ tailwindConfig: './tailwind.config.js', ++ }, + plugins: [ + '@snowpack/plugin-postcss', + ], @@ -90,6 +93,7 @@ When you load these with Snowpack, you should see these replaced with Tailwind C - [Official Tailwind Documentation][tailwind-postcss] - [PostCSS + Snowpack][snowpack-postcss] +[config-tailwind]: https://snowpack.dev/reference/configuration#devoptions.tailwindConfig [snowpack-postcss]: /guides/postcss/ [tailwind-jit]: https://tailwindcss.com/docs/just-in-time-mode [tailwind-postcss]: https://tailwindcss.com/docs/installation/#using-tailwind-with-postcss diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 8e2035604f..3b54a1901b 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -20,7 +20,7 @@ To generate a basic configuration file scaffold in your Snowpack project run `sn ## mode -**Type**: `"test" | "development" | "production"` +**Type**: `"test" | "development" | "production"` **Default**: `"development"` for `snowpack dev`, `"production"` for `snowpack build`. Specifies the "mode" that Snowpack should run in. The main impact of this is the value of `import.meta.env.MODE` at runtime, although there are some other key differences between modes: @@ -29,7 +29,7 @@ Specifies the "mode" that Snowpack should run in. The main impact of this is the ## root -**Type**: `string` +**Type**: `string` **Default**: `/` Specify the root of a project using Snowpack. (Previously: `config.cwd`) @@ -56,7 +56,7 @@ Can be a relative file path, an npm package, or a file within an npm package. Yo ## exclude -**Type**: `string[]` +**Type**: `string[]` **Default**: `['**/node_modules/**/*']` Exclude any files from the Snowpack pipeline. @@ -173,7 +173,7 @@ Configure the Snowpack dev server. ### devOptions.secure -**Type**: `boolean` or `object` +**Type**: `boolean` or `object` **Default**: `false` Toggles whether Snowpack dev server should use HTTPS with HTTP2 enabled. See the [SSL Certificates](/guides/https-ssl-certificates) Guide for more information. @@ -195,14 +195,14 @@ module.exports = { ### devOptions.hostname -**Type**: `string` +**Type**: `string` **Default**: `localhost` The hostname that the dev server is running on. Snowpack uses this information to configure the HMR websocket and properly open your browser on startup (see: [`devOptions.open`](#devoptions.open)). ### devOptions.port -**Type**: `number` +**Type**: `number` **Default**: `8080` The port the dev server runs on. @@ -215,7 +215,7 @@ Optional path to append to dev server url. May also include querystring paramete ### devOptions.fallback -**Type**: `string` +**Type**: `string` **Default**: `"index.html"` The HTML file to serve for non-resource routes. @@ -226,7 +226,7 @@ When using the Single-Page Application (SPA) pattern, this is the HTML "shell" f ### devOptions.open -**Type**: `string` +**Type**: `string` **Default**: `"**Default**"` Configures how the dev server opens in the browser when it starts. @@ -235,7 +235,7 @@ Any installed browser, e.g., "chrome", "firefox", "brave". Set "none" to disable ### devOptions.output -**Type**: `"stream" | "dashboard"` +**Type**: `"stream" | "dashboard"` **Default**: `"dashboard"` Set the output mode of the `dev` console: @@ -245,39 +245,54 @@ Set the output mode of the `dev` console: ### devOptions.hmr -**Type**: `boolean` +**Type**: `boolean` **Default**: `true` Toggles HMR on the Snowpack dev server. ### devOptions.hmrDelay -**Type**: `number` (milliseconds) +**Type**: `number` (milliseconds) **Default**: `0` Milliseconds to delay HMR-triggered browser update. ### devOptions.hmrPort -**Type**: `number` +**Type**: `number` **Default**: [`devOptions.port`](#devoptions.port) The port where Snowpack's HMR Websocket runs. ### devOptions.hmrErrorOverlay -**Type**: `boolean` +**Type**: `boolean` **Default**: `true` Toggles a browser overlay that displays JavaScript runtime errors when running HMR. ### devOptions.out -**Type**: `string` +**Type**: `string` **Default**: `"build"` _NOTE:_ Deprecated, see `buildOptions.out`. +### devOptions.tailwindConfig + +**Type**: `string` + +If using Tailwind, specify the path to your config file. e.g.: + +```js +// snowpack.config.mjs +export default { + devOptions: { + tailwindConfig: './tailwind.config.js', + }, +}; +``` + ## installOptions **Type**: `object` @@ -292,7 +307,7 @@ Configure how npm packages are installed and used. ### packageOptions.external -**Type**: `string[]` +**Type**: `string[]` **Example**: `"external": ["fs"]` Mark some imports as external. Snowpack will ignore these imports and leave them as-is in your final build. @@ -301,7 +316,7 @@ This is an advanced feature: Bare imports are not supported in any major browser ### packageOptions.source -**Type**: `"local" | "remote"` +**Type**: `"local" | "remote"` **Default**: `"local"` **Example**: `"source": "local"` @@ -321,7 +336,7 @@ Known dependencies to install with Snowpack. Used for installing packages any de #### packageOptions.polyfillNode -**Type**: `boolean` +**Type**: `boolean` **Default**: `false` This will automatically polyfill any Node.js dependencies as much as possible for the browser @@ -356,7 +371,7 @@ This option is only supported in `source="local"` mode. `source="remote"` does n #### packageOptions.packageLookupFields -**Type**: `string[]` +**Type**: `string[]` **Example**: `"packageLookupFields": ["svelte"]` Set custom lookup fields for dependency `package.json` file entrypoints, in addition to the defaults like "module", "main", etc. @@ -365,7 +380,7 @@ This option is only supported in `source="local"` mode. `source="remote"` does n #### packageOptions.packageExportLookupFields -**Type**: `string[]` +**Type**: `string[]` **Example**: `"packageExportLookupFields": ["svelte"]` Set custom lookup fields for dependency `package.json` ["exports" mappings.](https://nodejs.org/api/packages.html#packages_package_entry_points) @@ -394,7 +409,7 @@ Enable streaming package imports. Load dependencies from our remote CDN. Manage #### packageOptions.origin -**Type**: `string` +**Type**: `string` **Default**: `https://pkg.snowpack.dev` The remote origin to import packages from. When you import a new package, Snowpack will fetch those resources from this URL. @@ -403,14 +418,14 @@ Currently, the origin must implement a specific response format that Snowpack ca #### packageOptions.cache -**Type**: `string` +**Type**: `string` **Default**: `.snowpack` The location of your project cache folder, relative to the project root. Snowpack will save cached data to this folder. For example, if `packageOptions.types` is set to true, Snowpack will save TypeScript types to a `types` directory within this folder. #### packageOptions.types -**Type**: `boolean` +**Type**: `boolean` **Default**: `false` If true, Snowpack will download TypeScript types for every package. @@ -430,7 +445,7 @@ The local directory that we output your final build to. ### buildOptions.baseUrl -**Type**: `string` +**Type**: `string` **Default**: `/` In your HTML, replace all instances of `%PUBLIC_URL%` with this @@ -439,7 +454,7 @@ Inspired by the same [Create React App](https://create-react-app.dev/docs/using- ### buildOptions.clean -**Type**: `boolean` +**Type**: `boolean` **Default**: `true` Set to `false` to prevent Snowpack from deleting the build output folder (`buildOptions.out`) between builds. @@ -454,7 +469,7 @@ _NOTE:_ Deprecated, see `buildOptions.metaUrlPath`. ### buildOptions.metaUrlPath -**Type**: `string` +**Type**: `string` **Default**: `_snowpack` Rename the default directory for Snowpack metadata. In every build, Snowpack creates meta files for loading things like [HMR](/concepts/hot-module-replacement), [Environment Variables](/reference/environment-variables), and your built npm packages. @@ -463,7 +478,7 @@ When you build your project, this will be a path on disk relative to the `buildO ### buildOptions.sourcemap -**Type**: `boolean` +**Type**: `boolean` **Default**: `false` Generates source maps. @@ -472,14 +487,14 @@ Generates source maps. ### buildOptions.watch -**Type**: `boolean` +**Type**: `boolean` **Default**: `false` Run Snowpack's build pipeline through a file watcher. This option works best for local development when you have a custom frontend server (ex: Rails, PHP, etc.) and the Snowpack dev server cannot be used. ### buildOptions.htmlFragments -**Type**: `boolean` +**Type**: `boolean` **Default**: `false` Toggles whether HTML fragments are transformed like full HTML pages. @@ -488,21 +503,21 @@ HTML fragments are HTML files not starting with "". ### buildOptions.jsxFactory -**Type**: `string` +**Type**: `string` **Default**: `React.createElement` (or `h` if Preact import is detected) Set the name of the function used to create JSX elements. ### buildOptions.jsxFragment -**Type**: `string` +**Type**: `string` **Default**: `React.Fragment` (or `Fragment` if Preact import is detected) Set the name of the function used to create JSX fragments. ### buildOptions.jsxInject -**Type**: `string` +**Type**: `string` **Default**: `undefined` If set, this string can be used to automatically inject JSX imports for every JSX/TSX file. @@ -514,7 +529,7 @@ Configure your tests. ### testOptions.files -**Type**: `string[]` +**Type**: `string[]` **Default**: `["__tests__/**/*", "**/*.@(spec|test).*"]` Specifies your test files. If `NODE_ENV` is set to "test", Snowpack includes these files in your site build and scan them for installable dependencies. Otherwise, Snowpack excludes these files. diff --git a/examples/tailwind/README.md b/examples/tailwind/README.md new file mode 100644 index 0000000000..a0c32cd9a0 --- /dev/null +++ b/examples/tailwind/README.md @@ -0,0 +1,10 @@ +--- +layout: layouts/main.njk +title: Tailwind +--- + +### Learn more + +- [Tailwind docs on Snowpack][tailwind] + +[tailwind]: https://www.snowpack.dev/guides/tailwind-css/ diff --git a/examples/tailwind/package.json b/examples/tailwind/package.json new file mode 100644 index 0000000000..bc8145c027 --- /dev/null +++ b/examples/tailwind/package.json @@ -0,0 +1,17 @@ +{ + "name": "@snowpack/example-react-loadable-components", + "version": "0.0.1", + "private": true, + "scripts": { + "start": "snowpack dev", + "build": "snowpack build" + }, + "dependencies": {}, + "devDependencies": { + "@snowpack/plugin-postcss": "^1.3.0", + "postcss": "^8.2.15", + "postcss-cli": "^8.3.1", + "snowpack": "^3.4.0", + "tailwindcss": "^2.1.2" + } +} diff --git a/examples/tailwind/postcss.config.js b/examples/tailwind/postcss.config.js new file mode 100644 index 0000000000..46ec55d46b --- /dev/null +++ b/examples/tailwind/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + // other plugins can go here, such as autoprefixer + }, +}; diff --git a/examples/tailwind/public/global.css b/examples/tailwind/public/global.css new file mode 100644 index 0000000000..b5c61c9567 --- /dev/null +++ b/examples/tailwind/public/global.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/examples/tailwind/public/index.html b/examples/tailwind/public/index.html new file mode 100644 index 0000000000..64ccd64af5 --- /dev/null +++ b/examples/tailwind/public/index.html @@ -0,0 +1,31 @@ + + + + + Tailwind Example + + + +
+ +
+
+

+ “Tailwind CSS is the only framework that I've seen scale on large teams. It’s easy to + customize, adapts to any design, and the build size is tiny.” +

+
+
+
Sarah Dayan
+
Staff Engineer, Algolia
+
+
+
+ + diff --git a/examples/tailwind/snowpack.config.js b/examples/tailwind/snowpack.config.js new file mode 100644 index 0000000000..513d4e0cc3 --- /dev/null +++ b/examples/tailwind/snowpack.config.js @@ -0,0 +1,11 @@ +/** @type {import("snowpack").SnowpackUserConfig } */ +module.exports = { + mount: { + public: '/', + src: '/_dist', + }, + devOptions: { + tailwindConfig: './tailwind.config.js', + }, + plugins: ['@snowpack/plugin-postcss'], +}; diff --git a/examples/tailwind/tailwind.config.js b/examples/tailwind/tailwind.config.js new file mode 100644 index 0000000000..27fcf519d6 --- /dev/null +++ b/examples/tailwind/tailwind.config.js @@ -0,0 +1,5 @@ +module.exports = { + mode: 'jit', + purge: ['./public/**/*.html', './src/**/*.{js,jsx,ts,tsx,vue}'], + // specify other options here +}; diff --git a/snowpack/src/commands/dev.ts b/snowpack/src/commands/dev.ts index aa2062a2bb..dcd05b9d3c 100644 --- a/snowpack/src/commands/dev.ts +++ b/snowpack/src/commands/dev.ts @@ -683,7 +683,12 @@ export async function startServer( config, hmrEngine, }); - inMemoryBuildCache.set(cacheKey, fileBuilder); + // note: for Tailwind, CSS needs to avoid caching in dev server (Tailwind needs to handle rebuilding, not Snowpack) + const isTailwind = + config.devOptions.tailwindConfig && (fileLoc.endsWith('.css') || fileLoc.endsWith('.pcss')); + if (!isTailwind) { + inMemoryBuildCache.set(cacheKey, fileBuilder); + } } function handleFinalizeError(err: Error) { diff --git a/snowpack/src/config.ts b/snowpack/src/config.ts index 6772e3314e..656695a109 100644 --- a/snowpack/src/config.ts +++ b/snowpack/src/config.ts @@ -135,6 +135,7 @@ const configSchema = { hmrDelay: {type: 'number'}, hmrPort: {type: 'number'}, hmrErrorOverlay: {type: 'boolean'}, + tailwindConfig: {type: 'string'}, }, }, packageOptions: { diff --git a/snowpack/src/types.ts b/snowpack/src/types.ts index bc18aa6e14..780dead661 100644 --- a/snowpack/src/types.ts +++ b/snowpack/src/types.ts @@ -274,6 +274,7 @@ export interface SnowpackConfig { hmrDelay: number; hmrPort: number | undefined; hmrErrorOverlay: boolean; + tailwindConfig?: string; }; buildOptions: { out: string;