Skip to content

Commit ea90a9e

Browse files
committed
Expand why.md
1 parent 2292754 commit ea90a9e

File tree

1 file changed

+64
-8
lines changed

1 file changed

+64
-8
lines changed

packages/docs/src/why.md

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22

33
You might have a lot of questions about why the generated project is structured the way it is. This page aims to answer some of those questions.
44

5-
:::tip NOTE
6-
More content should be added to this page over time, there's a lot to explain.
7-
:::
8-
95
To learn more about the built files in the `dist` directory see [Files in `dist`](dist-files).
106

117
## Influences
@@ -16,24 +12,84 @@ But applications and libraries need different things.
1612

1713
Libraries such as [Vue core](https://github.com/vuejs/core), [Vue Router](https://github.com/vuejs/router) and [Pinia](https://github.com/vuejs/pinia/) have also heavily influenced the project structure used by this tool, especially the use of a `packages` directory and pnpm workspaces. Various other tools, such as `simple-git-hooks`, `lint-staged` and VitePress, have been chosen to align with those projects.
1814

19-
Those projects use [rollup](https://rollupjs.org/) directly for their builds, rather than Vite. Using rollup is more flexible, but using Vite has a few advantages:
15+
Those projects use [rollup](https://rollupjs.org/) directly for their builds, rather than Vite. Vite already uses rollup behind the scenes, but using it directly is more flexible. Using Vite as a wrapper has a few advantages:
2016

2117
- Vite is familiar to most members of the Vue community.
2218
- Using Vite keeps us closer to `create-vue`.
2319
- Vite has its own ecosystem of useful plugins.
2420

2521
In particular, the libraries mentioned above don't use `.vue` files in their source code. Compiling `.vue` files with rollup is certainly possible, but it's more convenient to reuse the same toolchain used to build Vue applications.
2622

27-
<!--
23+
## Multiple packages
2824

29-
## ESLint configuration
25+
The project is split into multiple packages. By default, these are in a directory called `packages`, plus a root package. Each package has its own `package.json` file.
26+
27+
These packages form a pnpm workspace, configured via `pnpm-workspace.yaml`. The workspace allows certain actions to be applied to all packages in one go, for example, running `pnpm install` at the root will install dependencies for all the packages.
28+
29+
Splitting the `package.json` in this way helps to keep things modular. It also helps to reduce the amount of noise in the `package.json` that gets published to the npm registry.
30+
31+
The project's root `package.json` uses `preinstall` and `postinstall` hooks. It's important that these are not in the `package.json` that's published to the npm registry, otherwise they would run when someone tries to install your package.
3032

3133
## TypeScript configuration
3234

35+
The TypeScript configuration is mostly done of a per-package basis. The configuration files are closely based on the files created by `create-vue`.
36+
37+
A root-level `tsconfig.json` is only created if ESLint is included. That is just used to check `eslint.config.ts`, which is at the root of the project. There currently aren't any other TS files that live outside the sub-packages.
38+
39+
Where possible we use `vue-tsc --build` to perform the type checks, the same as `create-vue`, but for the docs package that doesn't currently seem to be possible. We have `"vitePressExtensions": [".md"]` set in `vueCompilerOptions`, which allows `.md` files to be processed a bit like `.vue` files, allowing any Vue syntax to be type-checked. That setting triggers an error if we use `vue-tsc --build`, so we check the code and config files separately instead.
40+
41+
## ESLint configuration
42+
43+
The ESLint configuration is very closely based on `create-vue`.
44+
45+
While it is theoretically possible to have separate ESLint configurations for each package, that's unlikely to be useful in practice, so the configuration is at the root level of the project.
46+
47+
ESLint Stylistic can be used as a formatter. See https://eslint.style/guide/why for an explanation of the benefits of that package over dedicated formatters such as Prettier. If you want to use Prettier instead then you'll need to configure it yourself, at least for now.
48+
3349
## `simple-git-hooks` and `lint-staged`
3450

51+
`simple-git-hooks` is widely used in the Vue and Vite ecosystems to run tasks when files are committed to git. This helps to catch mistakes early.
52+
53+
Currently, we support using `simple-git-hooks` for running the type checks and running ESLint, via `lint-staged`. Using `lint-staged` ensures that only *staged* files are checked (i.e. those that are going to be included in the commit). By default, the project runs ESLint with the `--fix` flag, to automatically fix any problems, but you can remove that flag if you're concerned about code being unexpectedly mangled by the formatter.
54+
55+
Many projects also use `simple-git-hooks` to impose restrictions on the commit message. This isn't currently something configured by the tool.
56+
57+
We use a `postinstall` target in `scripts` to update the git hooks, ensuring they stay up to date for anyone developing the package. The documentation for `simple-git-hooks` warns against doing that, but it's important to note that the `postinstall` is in the project's root `package.json`, not the `package.json` that's published to the npm registry. It's only a problem if it's published to the registry.
58+
59+
## `.gitignore`
60+
61+
The `.gitignore` is similar to `create-vue`.
62+
63+
We use a single `.gitignore`, rather than having one in each package. This leads to some entries that target specific parts of individual packages, which might more naturally be configured using a separate `.gitignore` within that specific package.
64+
65+
A key reason for using a single file is that we can easily integrate it into other tools, such as ESLint.
66+
3567
## Vite configuration
3668

69+
The separate page [Files in `dist`](/dist-files) explains the reasoning behind some of the most important parts of `vite.config.mts`.
70+
71+
The Vue plugin is configured with `componentIdGenerator: 'filepath'`. This controls how the ids are generated for `<style scoped>`. The default strategy hashes the file contents, but only after other parts of the build have processed the file, leading to inconsistent hashes between development and production builds. Using the filepath instead helps to keep the ids stable across all the files in `dist`, so that any combination of JS and CSS files should work together.
72+
73+
[`vite-plugin-dts`](https://github.com/qmhc/vite-plugin-dts) is used to generate the `.d.ts` file. By default, this generates a separate `.d.ts` file for each input file, but `rollupTypes: true` merges them into a single file. Despite the naming similarity, that setting is unrelated to the build tool rollup.
74+
75+
As we can't build all the output files we need in one go, we instead run Vite three times. `emptyOutDir` is set to `false`, so that we don't lose the build artifacts from the other stages of the build. `rimraf` is used to clear the `dist` directory at the start of the build process.
76+
77+
In `rollupOptions` we configure `external: ['vue']`. This tells rollup to keep any imports from the `vue` package as imports, rather than pulling all the code into the built library. For output formats that don't support `import` it will be rewritten accordingly, e.g. using `require()` for CommonJS. For global (IIFE) builds, there is the extra setting `globals: { vue: 'Vue' }`, which tells rollup to rewrite imports like `import { ref } from 'vue'` as `const { ref } = Vue`, or code that's equivalent.
78+
3779
## `__DEV__` and `__TEST__`
3880

39-
-->
81+
The project supports 'global variables' for `__DEV__` and `__TEST__`. The `__TEST__` variable isn't included by default and requires the `--extended` flag to opt in.
82+
83+
While they are configured as global variables from a TypeScript perspective, and will be interpreted that way by tools such as IDEs and ESlint, they are actually statically replaced by Vite during the build. They also need to be configured in the docs and playground packages, as those packages use the library's source code directly.
84+
85+
If you need to add other variables like these, e.g. `__BROWSER__`, `__CI__`, `__SSR__`, you'll need to configure those yourself, using `__DEV__` and `__TEST__` as a starting point. In some cases you may need to make other changes to the build to generate extra files in `dist`, so consumers of your package can use the alternative builds.
86+
87+
For `__TEST__` we replace the value with a simple `true` or `false`, which can be configured using Vite's `define` option.
88+
89+
For `__DEV__` it's a little more complicated, because in some builds we replace it with `!(process.env.NODE_ENV === "production")`. This allows the downstream bundler to make the decision about what mode we're in. We can't use `define` for a complex value like this, so `@rollup/plugin-replace` is used instead.
90+
91+
## `jiti`
92+
93+
The package `jiti` is included so that ESLint can use a TypeScript configuration file:
94+
95+
- <https://eslint.org/docs/latest/use/configure/configuration-files#typescript-configuration-files>

0 commit comments

Comments
 (0)