@cooperco/nuxt-layer-base 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -19,6 +19,7 @@ Learn more in the official Nuxt Layers documentation: https://nuxt.com/docs/guid
19
19
  - TypeScript with strict mode enabled
20
20
  - ESLint via `@nuxt/eslint` with stylistic Vue template rules
21
21
  - Internationalization (i18n) via `@nuxtjs/i18n`
22
+ - Hints and best practices via `@nuxt/hints`
22
23
  - Nuxt DevTools enabled in development
23
24
  - Optional error and event logging to Loggly (client and server), disabled by default
24
25
 
@@ -46,7 +47,7 @@ export default defineNuxtConfig({
46
47
  })
47
48
  ```
48
49
 
49
- TypeScript strict mode and DevTools are active immediately. For ESLint, add a config in your app (see "ESLint in consumer apps").
50
+ TypeScript strict mode and DevTools are active immediately. For ESLint, add a config in your app (see "ESLint in consumer apps"). For `@nuxt/hints`, you must also install it as a dev dependency in your app (see "Hints and Best Practices (@nuxt/hints)").
50
51
 
51
52
  ### Internationalization (i18n)
52
53
 
@@ -94,6 +95,27 @@ const { t } = useI18n()
94
95
 
95
96
  Both global files (e.g., `locales/en.json`) and per‑component `<i18n>` blocks are supported.
96
97
 
98
+ ### Hints and Best Practices (@nuxt/hints)
99
+
100
+ This layer includes `@nuxt/hints`, which provides real-time suggestions for improving your application's performance, security, and best practices directly in your development environment.
101
+
102
+ #### Important: Runtime Dependency
103
+
104
+ Because `@nuxt/hints` injects runtime code into your components (to track hydration and other metrics), you **must** add `@nuxt/hints` to your app's `devDependencies` even though it is provided by the layer. This ensures that the bundler can resolve the injected imports.
105
+
106
+ ```bash
107
+ # npm
108
+ npm i -D @nuxt/hints
109
+
110
+ # pnpm
111
+ pnpm add -D @nuxt/hints
112
+
113
+ # yarn
114
+ yarn add -D @nuxt/hints
115
+ ```
116
+
117
+ *Note: If you are using a monorepo with workspaces (e.g., pnpm workspaces) where dependencies are hoisted to the root, this manual installation may not be necessary.*
118
+
97
119
  ### Logging (optional, Loggly‑backed)
98
120
 
99
121
  When enabled via environment variables, the base layer will:
@@ -174,16 +196,45 @@ import withNuxt from './.nuxt/eslint.config.mjs'
174
196
 
175
197
  export default withNuxt({
176
198
  rules: {
177
- // Stylistic
178
- '@stylistic/comma-dangle': ['error', 'never'],
179
-
180
- // TypeScript
181
- '@typescript-eslint/no-unused-vars': ['error', { caughtErrorsIgnorePattern: '^_' }],
182
-
183
- // Vue template
184
- 'vue/html-closing-bracket-newline': ['error', { multiline: 'never', selfClosingTag: { multiline: 'never' } }],
185
- 'vue/html-closing-bracket-spacing': ['error', { selfClosingTag: 'never' }],
186
- 'vue/html-indent': ['error', 2, { baseIndent: 0 }]
199
+ /* Stylistic */
200
+ '@stylistic/comma-dangle': [
201
+ 'error',
202
+ 'only-multiline'
203
+ ],
204
+ '@stylistic/no-tabs': [
205
+ 'error',
206
+ { allowIndentationTabs: true }
207
+ ],
208
+
209
+ /* TS */
210
+ '@typescript-eslint/no-unused-vars': [
211
+ 'error',
212
+ { caughtErrorsIgnorePattern: '^_' }
213
+ ],
214
+
215
+ /* Vue */
216
+ 'vue/html-closing-bracket-newline': [
217
+ 'error',
218
+ { multiline: 'never', selfClosingTag: { multiline: 'never' } }
219
+ ],
220
+ 'vue/html-closing-bracket-spacing': [
221
+ 'error',
222
+ { selfClosingTag: 'never' }
223
+ ],
224
+ 'vue/html-indent': [
225
+ 'error', 'tab',
226
+ { baseIndent: 0 }
227
+ ],
228
+ 'vue/multi-word-component-names': ['error', {
229
+ ignores: []
230
+ }],
231
+ 'vue/component-name-in-template-casing': [
232
+ 'error',
233
+ 'kebab-case',
234
+ { registeredComponentsOnly: false, ignores: [] }
235
+ ],
236
+ 'vue/component-options-name-casing': ['error', 'kebab-case'],
237
+ 'vue/component-definition-name-casing': ['error', 'kebab-case']
187
238
  }
188
239
  })
189
240
  ```
@@ -202,62 +253,62 @@ export default withNuxt({
202
253
  Notes
203
254
  - The base layer enables stylistic mode via Nuxt (`eslint.config.stylistic: true`).
204
255
  - Do not use Prettier alongside stylistic rules; remove Prettier configs/plugins from your app to avoid conflicts.
256
+ - Tabs are allowed for indentation (including in Vue templates). The `no-tabs` rule is enabled but permits indentation tabs.
205
257
 
206
258
  What this ESLint config enforces (in plain English)
207
259
 
208
260
  - Base: It starts from Nuxt’s generated, project‑aware flat config (via `@nuxt/eslint`), then turns on stylistic mode for consistent formatting in JS/TS/Vue files.
209
261
  - This layer adds a few focused rules to keep things consistent and practical:
210
- - `@stylistic/comma-dangle: 'never'` — Disallow trailing commas in arrays/objects.
211
- - Bad:
212
- ```js
213
- const user = {
214
- id: 1,
215
- name: 'Ada',
216
- }
217
- ```
218
- - Good:
262
+ - `@stylistic/comma-dangle: 'only-multiline'` — Allow trailing commas only when the list spans multiple lines; disallow them on single‑line lists.
263
+ - Good (multiline, trailing comma ok):
219
264
  ```js
220
265
  const user = {
221
- id: 1,
222
- name: 'Ada'
266
+ id: 1,
267
+ name: 'Ada',
223
268
  }
224
269
  ```
270
+ - Good (single‑line, no trailing comma): `const arr = [1, 2, 3]`
271
+ - `@stylistic/no-tabs` with `{ allowIndentationTabs: true }` — Tabs are allowed for indentation but tabs elsewhere are flagged.
225
272
  - `@typescript-eslint/no-unused-vars` with `{ caughtErrorsIgnorePattern: '^_' }` — Flag unused variables, but allow a try/catch parameter that starts with `_` when you don’t use it.
226
273
  - Good (explicitly ignored):
227
274
  ```ts
228
275
  try {
229
- risky()
276
+ risky()
230
277
  }
231
278
  catch (_err) {
232
- // intentionally ignored
279
+ // intentionally ignored
233
280
  }
234
281
  ```
235
282
  - `vue/html-closing-bracket-newline: { multiline: 'never', selfClosingTag: { multiline: 'never' } }` — Don’t put a newline before a closing bracket, even for multi‑line attribute lists.
236
283
  - Bad:
237
284
  ```vue
238
- <MyComp
239
- a="1"
240
- b="2"
285
+ <my-comp
286
+ a="1"
287
+ b="2"
241
288
  />
242
289
  ```
243
290
  - Good:
244
291
  ```vue
245
- <MyComp
246
- a="1"
247
- b="2" />
292
+ <my-comp
293
+ a="1"
294
+ b="2" />
248
295
  ```
249
296
  - `vue/html-closing-bracket-spacing: { selfClosingTag: 'never' }` — No space before a self‑closing `/>`.
250
- - Bad: `<MyComp />`
251
- - Good: `<MyComp/>`
252
- - `vue/html-indent: [2, { baseIndent: 0 }]` — Two‑space indentation in templates.
297
+ - Bad: `<my-comp />`
298
+ - Good: `<my-comp/>`
299
+ - `vue/html-indent: ['tab', { baseIndent: 0 }]` — Use tabs for indentation in Vue templates.
253
300
  - Example:
254
301
  ```vue
255
302
  <template>
256
- <div>
257
- <span>Text</span>
258
- </div>
303
+ <div>
304
+ <span>Text</span>
305
+ </div>
259
306
  </template>
260
307
  ```
308
+ - `vue/multi-word-component-names` — Enforce multi‑word component names (no single generic names like `Header` conflicts). Configure ignores if needed.
309
+ - `vue/component-name-in-template-casing: 'kebab-case'` — In templates, component tags must be kebab‑case (e.g., `<my-widget/>`, not `<MyWidget/>`).
310
+ - `vue/component-options-name-casing: 'kebab-case'` — In SFC component options, the `name` should be kebab‑case.
311
+ - `vue/component-definition-name-casing: 'kebab-case'` — For component definitions in script, enforce kebab‑case names.
261
312
 
262
313
  ### TypeScript in consumer apps
263
314
 
package/eslint.config.mjs CHANGED
@@ -32,7 +32,17 @@ export default withNuxt({
32
32
  'vue/html-indent': [
33
33
  'error', 'tab',
34
34
  { baseIndent: 0 }
35
- ]
35
+ ],
36
+ 'vue/multi-word-component-names': ['error', {
37
+ ignores: []
38
+ }],
39
+ 'vue/component-name-in-template-casing': [
40
+ 'error',
41
+ 'kebab-case',
42
+ { registeredComponentsOnly: false, ignores: [] }
43
+ ],
44
+ 'vue/component-options-name-casing': ['error', 'kebab-case'],
45
+ 'vue/component-definition-name-casing': ['error', 'kebab-case']
36
46
  }
37
47
  })
38
48
 
package/nuxt.config.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable nuxt/nuxt-config-keys-order */
2
2
  export default defineNuxtConfig({
3
- modules: ['@nuxt/eslint', '@nuxtjs/i18n'],
3
+ modules: ['@nuxt/eslint', '@nuxtjs/i18n', '@nuxt/hints'],
4
4
  devtools: { enabled: true },
5
5
  compatibilityDate: '2025-07-15',
6
6
 
@@ -30,6 +30,10 @@ export default defineNuxtConfig({
30
30
  config: {
31
31
  stylistic: true
32
32
  }
33
+ },
34
+
35
+ i18n: {
36
+ defaultLocale: 'en'
33
37
  }
34
38
 
35
- })
39
+ })
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "@cooperco/nuxt-layer-base",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "main": "./nuxt.config.ts",
6
+ "author": "cooperco",
7
+ "description": "Base Nuxt layer for cooperco projects",
8
+ "license": "MIT",
6
9
  "scripts": {
7
10
  "dev": "nuxt dev",
8
- "lint": "nuxt prepare && eslint .",
9
- "lint:fix": "nuxt prepare && eslint . --fix",
10
- "typecheck": "nuxt prepare && vue-tsc -b --noEmit"
11
+ "lint": "eslint .",
12
+ "lint:fix": "eslint . --fix",
13
+ "typecheck": "nuxt typecheck"
11
14
  },
12
- "description": "Base Nuxt layer for cooperco projects",
13
15
  "publishConfig": {
14
16
  "access": "public",
15
17
  "registry": "https://registry.npmjs.org/"
@@ -19,16 +21,15 @@
19
21
  "url": "git+https://github.com/Cryobank/nuxt-layers.git",
20
22
  "directory": "layers/base"
21
23
  },
22
- "author": "cooperco",
23
- "license": "MIT",
24
24
  "dependencies": {
25
- "@nuxt/eslint": "^1.10.0",
25
+ "@nuxt/hints": "^1.0.0-alpha.5",
26
26
  "@nuxtjs/i18n": "^10.2.1",
27
- "nuxt": "^4.2.1"
27
+ "nuxt": "^4.2.2"
28
28
  },
29
29
  "devDependencies": {
30
- "@nuxt/test-utils": "^3.20.1",
31
- "eslint": "^9.39.1",
32
- "vue-tsc": "^3.1.4"
30
+ "@nuxt/eslint": "^1.12.1",
31
+ "@nuxt/test-utils": "^3.23.0",
32
+ "eslint": "^9.39.2",
33
+ "vue-tsc": "^3.2.2"
33
34
  }
34
35
  }