Skip to content

Commit 929aca2

Browse files
committed
Switch to prodDevtools: true for 'dev' builds
1 parent 0753d06 commit 929aca2

File tree

3 files changed

+33
-15
lines changed

3 files changed

+33
-15
lines changed

packages/create-vue-lib/src/template/base/config/packages/@projectName@/package.json.ejs

+1-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
<%_ } _%>
5050
"@vue/tsconfig": "^0.7.0",
5151
"copyfiles": "^2.4.1",
52-
"cross-env": "^7.0.3",
5352
"jsdom": "^26.0.0",
5453
"npm-run-all2": "^7.0.2",
5554
"publint": "^0.3.8",
@@ -73,7 +72,7 @@
7372
"type-check": "vue-tsc --build",
7473
"lint:package": "publint",
7574
"build:copy": "copyfiles -f ../../README.md .",
76-
"build:dev": "cross-env NODE_ENV=development vite build --mode development",
75+
"build:dev": "vite build --mode development",
7776
"build:neutral": "vite build --mode neutral",
7877
"build:prod": "vite build --mode production",
7978
"build": "run-s clean:dist build:* type-check lint:package"

packages/create-vue-lib/src/template/base/config/packages/@projectName@/vite.config.mts.ejs

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default defineConfig(({ mode }): UserConfig => {
1313
throw new Error(`Unknown mode: ${mode}`)
1414
}
1515

16-
const expectedNodeEnv = mode === 'neutral' ? 'production' : mode
16+
const expectedNodeEnv = mode === 'test' ? 'test' : 'production'
1717
const nodeEnv = process.env.NODE_ENV
1818

1919
if (nodeEnv !== expectedNodeEnv) {
@@ -37,7 +37,8 @@ export default defineConfig(({ mode }): UserConfig => {
3737
}),
3838
vue({
3939
features: {
40-
componentIdGenerator: 'filepath'
40+
componentIdGenerator: 'filepath',
41+
prodDevtools: mode === 'development'
4142
}
4243
}),
4344
dtsPlugin

packages/docs/src/dist-files.md

+29-11
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,33 @@ There are pros and cons with either approach, but the project scaffolded with th
5656

5757
### Development vs production
5858

59-
When building `.vue` files, the SFC compiler needs to know whether to generate a development or production build. The main difference is that a development build is fully compatible with Vue Devtools, whereas a production build only has limited Devtools support. Externally available properties, like `$props` and `$attrs`, will be shown in the Devtools in either build, but component state inside `<script setup>` will only be exposed in development builds.
59+
For applications, the distinction between development and production is usually clear.
6060

61-
They also differ in how they compile type-based prop definitions. Development builds will try to generate a helpful runtime `props` option, whereas a production build will aim for minimal code.
61+
For libraries, there are two build processes to consider: building the library itself and building the application. The consuming application might also not have a build process, e.g. for sites using libraries from a CDN.
6262

63-
You can see the differences for yourself in the Vue Playground at <https://play.vuejs.org/>. The compiled component is visible in the JS tab, and you can toggle between `DEV` and `PROD` using the button at the top of the page.
63+
Rather than a clear split between development and production, we instead have three stages: developing the library, developing the consuming application, and finally production. The first stage, developing the library itself, doesn't impact what we publish to npm, so we can ignore that here.
6464

65-
But having two different compiled forms means we need to commit to which one we want when we build the library.
65+
The production stage is also relatively straightforward.
6666

67-
To accommodate this, we need to generate `dev` and `prod` builds, even when the downstream application is using a bundler. The `package.json` then tells the bundler which one to use in each case.
67+
The stage that poses the most challenges is developing the consuming application. We need to build our library in such a way that it'll work well during that stage.
68+
69+
When building `.vue` files, the SFC compiler needs to know whether to generate a development or production build. There are several differences between development and production builds, but for now we'll just focus on three of them:
70+
71+
1. A development build is fully compatible with Vue Devtools, whereas a production build only has limited Devtools support. Externally available properties, like `$props` and `$attrs`, will be shown in the Devtools in either build, but component state inside `<script setup>` will only be exposed in development builds.
72+
2. Type-based prop definitions are compiled to a helpful runtime equivalent in a development build, whereas a production build will aim for minimal code.
73+
3. A development build includes the full (absolute) file path of each `.vue` file in the built code, under a property called `__file`.
74+
75+
You can see the first two differences for yourself in the Vue Playground at <https://play.vuejs.org/>. The compiled component is visible in the JS tab, and you can toggle between `DEV` and `PROD` using the button at the top of the page. The difference in the `__file` property isn't apparent without the full Vite build-chain.
76+
77+
Having two different compiled forms means we need to commit to which one we want when we build the library.
78+
79+
Including the full path in `__file` is a headache. The build output of a library should be consistent between users, so it shouldn't depend on where the project is stored on the local filesystem. The full path can also potentially include sensitive information, such as usernames or company names, risking doxxing the library's author.
80+
81+
Ideally we'd want a third mode here, aimed at building development builds of libraries. Devtools support and type-based prop compilation should work like a development build, but features like the `__file` property should behave like production, as they aren't relevant to developing the downstream application.
82+
83+
That doesn't exist, but we can get close by using a production build with `prodDevtools: true`. That enables Devtools support, but sadly we won't get the improved runtime props definition.
84+
85+
To accommodate this, we need to generate `dev` and `prod` builds, even when the downstream application is using a bundler. The `dev` builds still use production mode, but with `prodDevtools: true`. The `package.json` then tells the downstream bundler which one to use in each case.
6886

6987
### SSR
7088

@@ -81,7 +99,7 @@ This is a CommonJS build. It is intended to be used in Node applications that us
8199
Some features of this build:
82100
- The file is not minified, as it isn't used in the browser.
83101
- The global `__DEV__` flag will depend on the runtime value of `process.env.NODE_ENV`. This is only relevant if you're using it in your library code.
84-
- SFCs will be compiled in production mode.
102+
- SFCs will be compiled in production mode, without `prodDevtools: true`.
85103

86104
There is an argument for having separate `dev` and `prod` builds, but the generated project won't currently be configured that way.
87105

@@ -108,7 +126,7 @@ This file exposes the library as an ES module. It is intended to be used during
108126
Some features of this build:
109127
- The file is not minified, to make debugging easier.
110128
- The global `__DEV__` flag will be set to `true`. This is only relevant if you're using it in your library code.
111-
- SFCs will be compiled in development mode.
129+
- SFCs will be compiled in production mode, but with `prodDevtools: true`.
112130

113131
In production, you would use either `<name>.esm-browser.prod.js` or `<name>.esm-bundler.prod.mjs` instead.
114132

@@ -138,7 +156,7 @@ It's a production build, so in real code the versions should be pinned.
138156
Some features of this build:
139157
- The file is minified, reducing its size. Note that Vite doesn't fully minify `esm` builds for libraries.
140158
- The global `__DEV__` flag will be set to `false` and dead code removed. This is only relevant if you're using it in your code.
141-
- SFCs will be compiled in production mode.
159+
- SFCs will be compiled in production mode, without `prodDevtools: true`.
142160

143161
During development, you'd normally use `<name>.esm.dev.mjs` instead.
144162

@@ -149,9 +167,9 @@ This is a production ES module build, intended to be used by a bundler.
149167
Some features of this build:
150168
- The file is not minified. The bundler will be expected to handle that.
151169
- The global `__DEV__` variable will depend on the bundler's value for `process.env.NODE_ENV`.
152-
- SFCs will be compiled in production mode.
170+
- SFCs will be compiled in production mode, without `prodDevtools: true`.
153171

154-
From a bundler's perspective, the only significant difference between this build and the `<name>.esm.dev.mjs` build is that `.vue` files are built in production mode. If you aren't using `.vue` files in your library code then this file can be used in both development and production. That would be similar to libraries like Vue core, Vue Router and Pinia, which just have an `esm-bundler` build, with no distinction between `dev` and `prod`. In that scenario, `<name>.esm.dev.mjs` is only used in the browser, so it could be renamed to something like `<name>.esm-browser.dev.js`.
172+
From a bundler's perspective, the only significant difference between this build and the `<name>.esm.dev.mjs` build is that `.vue` files are built without `prodDevtools: true`. If you aren't using `.vue` files in your library code then this file can be used in both development and production. That would be similar to libraries like Vue core, Vue Router and Pinia, which just have an `esm-bundler` build, with no distinction between `dev` and `prod`. In that scenario, `<name>.esm.dev.mjs` is only used in the browser, so it could be renamed to something like `<name>.esm-browser.dev.js`.
155173

156174
### `<name>.global.dev.js` and `<name>.global.prod.js`
157175

@@ -183,7 +201,7 @@ In production applications, the `prod` builds of both `vue` and `@skirtle/exampl
183201
The differences between the `dev` and `prod` builds are:
184202
- `prod` is minified, `dev` isn't.
185203
- `dev` sets `__DEV__` to `true`, `prod` sets it to `false`, with any dead code removed.
186-
- SFCs will be compiled in development or production modes accordingly.
204+
- `dev` builds use `prodDevtools: true`.
187205

188206
## `build:dev`, `build:neutral`, `build:prod`
189207

0 commit comments

Comments
 (0)