-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,5 +4,5 @@ | |
**/coverage | ||
**/dist | ||
**/docs | ||
**/codemods/**/__testfixtures__ | ||
**/snap | ||
pnpm-lock.yaml |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
--- | ||
id: build | ||
title: Build | ||
--- | ||
|
||
The Vite build setup provided is the culmination of several attempts to make the TanStack libraries work in all environments, including ESM, CJS, the various TypeScript module resolution options, and a diverse bundler ecosystem. | ||
|
||
# Usage | ||
|
||
The build config is quite opinionated, as it is designed to work with our internal libraries. If you follow the below instructions, it _may_ work for your library too! | ||
|
||
## package.json | ||
|
||
- Ensure `"type": "module"` is set. | ||
- Ensure you have [Vite](https://www.npmjs.com/package/vite) installed. Installing [Publint](https://www.npmjs.com/package/publint) is also recommended. | ||
- Change your build script to `"build": "vite build && publint --strict"` | ||
- Ensure you have an `"exports"` field. We use this, but you might have different requirements: | ||
|
||
```json | ||
{ | ||
"exports": { | ||
".": { | ||
"import": { | ||
"types": "./dist/esm/index.d.ts", | ||
"default": "./dist/esm/index.js" | ||
}, | ||
"require": { | ||
"types": "./dist/cjs/index.d.cts", | ||
"default": "./dist/cjs/index.cjs" | ||
} | ||
}, | ||
"./package.json": "./package.json" | ||
} | ||
} | ||
``` | ||
|
||
## tsconfig.json | ||
|
||
- Ensure your `"include"` field includes `"vite.config.ts"`. | ||
- Set `"moduleResolution"` to `"bundler"`. | ||
|
||
## vite.config.ts | ||
|
||
- Wrap your `defineConfig` in `mergeConfig` (also exported from Vite). | ||
- Add `tanstackBuildConfig` into `mergeConfig`. | ||
- Note: Please avoid modifying `build` in your own `defineConfig`. | ||
- See an example below: | ||
|
||
```ts | ||
import { defineConfig, mergeConfig } from 'vite' | ||
import { tanstackBuildConfig } from '@tanstack/config/build' | ||
|
||
export default mergeConfig( | ||
tanstackBuildConfig({ | ||
entry: 'src/index.ts', | ||
srcDir: 'src', | ||
}), | ||
defineConfig({ | ||
// Add any custom options here, such as framework plugins | ||
}), | ||
) | ||
``` | ||
|
||
# Caveats | ||
|
||
While this config _will_ work with most frameworks with a Vite adapter, it doesn't mean you _should_ use it for all frameworks. For instance, Svelte publishes [@sveltejs/package](https://www.npmjs.com/package/@sveltejs/package), and Angular publishes [ng-packagr](https://www.npmjs.com/package/ng-packagr). When a framework-specific build tool exists, this should be preferred. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# React + TypeScript + Vite | ||
|
||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. | ||
|
||
Currently, two official plugins are available: | ||
|
||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh | ||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh | ||
|
||
## Expanding the ESLint configuration | ||
|
||
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: | ||
|
||
- Configure the top-level `parserOptions` property like this: | ||
|
||
```js | ||
export default { | ||
// other rules... | ||
parserOptions: { | ||
ecmaVersion: 'latest', | ||
sourceType: 'module', | ||
project: ['./tsconfig.json', './tsconfig.node.json'], | ||
tsconfigRootDir: __dirname, | ||
}, | ||
} | ||
``` | ||
|
||
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` | ||
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` | ||
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "react-integration", | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"test:build": "vite build && vitest" | ||
}, | ||
"dependencies": { | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0" | ||
}, | ||
"devDependencies": { | ||
"@tanstack/config": "<1.0.0", | ||
"@types/react": "^18.2.46", | ||
"@types/react-dom": "^18.2.18", | ||
"@vitejs/plugin-react": "^4.2.1" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); | ||
const useClient = require("./use-client.cjs"); | ||
const nested = require("./nested/nested.cjs"); | ||
exports.Component = useClient.Component; | ||
exports.test = nested.test; | ||
//# sourceMappingURL=index.cjs.map |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './use-client'; | ||
export * from './nested/nested'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); | ||
const test = "Hello world!"; | ||
exports.test = test; | ||
//# sourceMappingURL=nested.cjs.map |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export declare const test = "Hello world!"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); | ||
const jsxRuntime = require("react/jsx-runtime"); | ||
const Component = () => { | ||
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Hello world!" }); | ||
}; | ||
exports.Component = Component; | ||
//# sourceMappingURL=use-client.cjs.map |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export declare const Component: () => import("react/jsx-runtime").JSX.Element; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './use-client'; | ||
export * from './nested/nested'; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export declare const test = "Hello world!"; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export declare const Component: () => import("react/jsx-runtime").JSX.Element; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './use-client' | ||
export * from './nested/nested' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const test = 'Hello world!' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
'use client' | ||
|
||
export const Component = () => { | ||
return <div>Hello world!</div> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { readFileSync } from 'node:fs' | ||
import { fileURLToPath } from 'node:url' | ||
import { dirname, resolve } from 'node:path' | ||
import { describe, expect, it } from 'vitest' | ||
|
||
const __dirname = dirname(fileURLToPath(import.meta.url)) | ||
const rootDir = resolve(__dirname, '..') | ||
|
||
const esmExtensions = ['.js', '.js.map', '.d.ts'] | ||
const cjsExtensions = ['.cjs', '.cjs.map', '.d.cts'] | ||
|
||
const files = ['index', 'use-client', 'nested/nested'] | ||
|
||
describe('Check React build output', () => { | ||
it('should build the same ESM output', () => { | ||
files.forEach((file) => { | ||
esmExtensions.forEach((ext) => { | ||
expect( | ||
readFileSync(`${rootDir}/dist/esm/${file}${ext}`).toString(), | ||
).toMatchFileSnapshot(`${rootDir}/snap/esm/${file}${ext}`) | ||
}) | ||
}) | ||
}) | ||
|
||
it('should build the same CJS output', () => { | ||
files.forEach((file) => { | ||
cjsExtensions.forEach((ext) => { | ||
expect( | ||
readFileSync(`${rootDir}/dist/cjs/${file}${ext}`).toString(), | ||
).toMatchFileSnapshot(`${rootDir}/snap/cjs/${file}${ext}`) | ||
}) | ||
}) | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "ES2020", | ||
"useDefineForClassFields": true, | ||
"lib": ["ES2020", "DOM", "DOM.Iterable"], | ||
"module": "ESNext", | ||
"skipLibCheck": true, | ||
|
||
/* Bundler mode */ | ||
"moduleResolution": "bundler", | ||
"allowImportingTsExtensions": true, | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
"noEmit": true, | ||
"jsx": "react-jsx", | ||
|
||
/* Linting */ | ||
"strict": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"noFallthroughCasesInSwitch": true | ||
}, | ||
"include": ["src", "tests", "vite.config.ts"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { mergeConfig, defineConfig } from 'vitest/config' | ||
import react from '@vitejs/plugin-react' | ||
import { tanstackBuildConfig } from '@tanstack/config/build' | ||
|
||
export default mergeConfig( | ||
tanstackBuildConfig({ | ||
entry: 'src/index.ts', | ||
srcDir: 'src', | ||
exclude: ['src/__tests__'], | ||
}), | ||
defineConfig({ | ||
plugins: [react()], | ||
test: { | ||
name: 'react', | ||
watch: false, | ||
}, | ||
}), | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Vue 3 + TypeScript + Vite | ||
|
||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more. | ||
|
||
## Recommended IDE Setup | ||
|
||
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). | ||
|
||
## Type Support For `.vue` Imports in TS | ||
|
||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. | ||
|
||
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: | ||
|
||
1. Disable the built-in TypeScript Extension | ||
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette | ||
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` | ||
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"name": "vue-integration", | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"test:build": "vite build && vitest" | ||
}, | ||
"dependencies": { | ||
"vue": "^3.3.11" | ||
}, | ||
"devDependencies": { | ||
"@tanstack/config": "<1.0.0", | ||
"@vitejs/plugin-vue": "^4.5.2" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
"use strict"; | ||
const App_vue_vue_type_script_setup_true_lang = require("./App.vue2.cjs"); | ||
require("./App.vue3.cjs"); | ||
const _pluginVue_exportHelper = require("./_virtual/_plugin-vue_export-helper.cjs"); | ||
const App = /* @__PURE__ */ _pluginVue_exportHelper(App_vue_vue_type_script_setup_true_lang, [["__scopeId", "data-v-57d0a178"]]); | ||
module.exports = App; | ||
//# sourceMappingURL=App.vue.cjs.map |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>; | ||
export default _default; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
"use strict"; | ||
const vue = require("vue"); | ||
const HelloWorld = require("./components/HelloWorld.vue.cjs"); | ||
const _sfc_main = /* @__PURE__ */ vue.defineComponent({ | ||
__name: "App", | ||
setup(__props) { | ||
return (_ctx, _cache) => { | ||
return vue.openBlock(), vue.createBlock(HelloWorld, { msg: "Vite + Vue" }); | ||
}; | ||
} | ||
}); | ||
module.exports = _sfc_main; | ||
//# sourceMappingURL=App.vue2.cjs.map |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
"use strict"; | ||
//# sourceMappingURL=App.vue3.cjs.map |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
"use strict"; | ||
const _export_sfc = (sfc, props) => { | ||
const target = sfc.__vccOpts || sfc; | ||
for (const [key, val] of props) { | ||
target[key] = val; | ||
} | ||
return target; | ||
}; | ||
module.exports = _export_sfc; | ||
//# sourceMappingURL=_plugin-vue_export-helper.cjs.map |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.