@questwork/q-utilities 0.1.32 → 0.1.34
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/dist/q-utilities.cjs +4838 -11
- package/dist/q-utilities.d.ts +245 -0
- package/dist/q-utilities.esm.js +3766 -1988
- package/dist/q-utilities.iife.js +4840 -11
- package/dist/q-utilities.umd.js +4841 -10
- package/package.json +1 -1
- package/.github/workflows/publish.yml +0 -60
- package/BEST_PRACTICES.md +0 -217
- package/BUILDING_JS_TS_LIBRARY.md +0 -321
- package/dist/q-utilities.cjs.map +0 -1
- package/dist/q-utilities.esm.js.map +0 -1
- package/dist/q-utilities.iife.js.map +0 -1
- package/dist/q-utilities.umd.js.map +0 -1
- package/eslint.config.js +0 -3
- package/tests/runtime-test.js +0 -563
- package/tsconfig.json +0 -28
- package/vite.config.js +0 -73
- package/vitest.config.js +0 -9
package/package.json
CHANGED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
name: Publish to npm on Tag
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
tags:
|
|
5
|
-
- 'v*'
|
|
6
|
-
workflow_dispatch:
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
publish:
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
permissions:
|
|
12
|
-
contents: read
|
|
13
|
-
id-token: write # OIDC
|
|
14
|
-
# environment: production
|
|
15
|
-
steps:
|
|
16
|
-
- uses: actions/checkout@v4
|
|
17
|
-
with:
|
|
18
|
-
fetch-depth: 0 # Needed to get tag information
|
|
19
|
-
|
|
20
|
-
- name: Install pnpm
|
|
21
|
-
uses: pnpm/action-setup@v4
|
|
22
|
-
with:
|
|
23
|
-
version: 9
|
|
24
|
-
|
|
25
|
-
- uses: actions/setup-node@v4
|
|
26
|
-
with:
|
|
27
|
-
node-version: 20.x
|
|
28
|
-
registry-url: https://registry.npmjs.org/
|
|
29
|
-
cache: pnpm
|
|
30
|
-
|
|
31
|
-
- name: Install dependencies
|
|
32
|
-
run: pnpm install
|
|
33
|
-
|
|
34
|
-
- name: Build
|
|
35
|
-
run: |
|
|
36
|
-
BUILD_COMMAND=$(node -p "(require('./package.json').scripts || {}).build")
|
|
37
|
-
if [ "$BUILD_COMMAND" = "undefined" ]; then
|
|
38
|
-
echo "::notice::Can't find a build script in package.json, skip."
|
|
39
|
-
else
|
|
40
|
-
pnpm run build
|
|
41
|
-
fi
|
|
42
|
-
|
|
43
|
-
# - name: Publish to npm
|
|
44
|
-
# # if: steps.version-check.outputs.should_publish == 'true'
|
|
45
|
-
# run: pnpm publish --no-git-checks --access public
|
|
46
|
-
# env:
|
|
47
|
-
# NODE_AUTH_TOKEN: ${{ secrets.QW_NPM_TOKEN }}
|
|
48
|
-
|
|
49
|
-
- name: Update npm
|
|
50
|
-
run: |
|
|
51
|
-
NPM_VERSION=$(npm -v)
|
|
52
|
-
echo "Current npm version: $NPM_VERSION"
|
|
53
|
-
if ! npx semver -r ">=11.5.1" "$NPM_VERSION"; then
|
|
54
|
-
echo "npm version $NPM_VERSION is too old. Installing latest npm..."
|
|
55
|
-
npm install -g npm@latest
|
|
56
|
-
echo "Updated npm version: $(npm -v)"
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
- name: Publish to npm
|
|
60
|
-
run: npm publish --no-git-checks --access public
|
package/BEST_PRACTICES.md
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
# Best Practices for Questwork Model Projects
|
|
2
|
-
|
|
3
|
-
This document outlines the best practices for developing and maintaining Questwork model projects. It is intended to guide both AI agents and developers on key principles and considerations.
|
|
4
|
-
|
|
5
|
-
## 1. Code Structure
|
|
6
|
-
|
|
7
|
-
### 1.1 File Organization
|
|
8
|
-
- **Models**: Place all data models in `lib/models/` directory
|
|
9
|
-
- **Constants**: Place all constant definitions in `lib/constants/` directory
|
|
10
|
-
- **Helpers**: Place utility functions in `lib/helpers/` directory
|
|
11
|
-
- **Tests**: Place unit tests next to the corresponding model files with `.spec.ts` extension
|
|
12
|
-
|
|
13
|
-
### 1.2 Export Patterns
|
|
14
|
-
- Place all exports at the bottom of the file
|
|
15
|
-
- Separate named exports from type exports
|
|
16
|
-
- Use clear, consistent export patterns
|
|
17
|
-
|
|
18
|
-
Example:
|
|
19
|
-
```typescript
|
|
20
|
-
export {
|
|
21
|
-
BaseModel
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export type {
|
|
25
|
-
BaseModelOptions, BaseModelUpdate
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## 2. TypeScript Best Practices
|
|
30
|
-
|
|
31
|
-
### 2.1 Type Definitions
|
|
32
|
-
- Use interfaces for complex type definitions
|
|
33
|
-
- Use `as const` for constant objects to create literal types
|
|
34
|
-
- Define types for all function parameters and return values
|
|
35
|
-
|
|
36
|
-
### 2.2 Coding Style
|
|
37
|
-
- **Semi-colons**: Do not use semi-colons at the end of lines
|
|
38
|
-
- **Naming Conventions**:
|
|
39
|
-
- Constants: `CONSTANT_CASE`
|
|
40
|
-
- Interfaces: `PascalCase`
|
|
41
|
-
- Classes: `PascalCase`
|
|
42
|
-
- Methods and functions: `camelCase`
|
|
43
|
-
- Properties: `camelCase`
|
|
44
|
-
- Private properties: `_underscorePrefix`
|
|
45
|
-
- **Ordering**:
|
|
46
|
-
- Place `[key: string]: any` at the top of class definitions
|
|
47
|
-
- Order class properties in alphabetical order
|
|
48
|
-
- Order class methods in alphabetical order
|
|
49
|
-
|
|
50
|
-
### 2.3 Model Patterns
|
|
51
|
-
- Extend appropriate base classes for shared functionality
|
|
52
|
-
- Use `init()` method for object creation
|
|
53
|
-
- Include static methods for testing purposes
|
|
54
|
-
- Define arrays to restrict updatable fields
|
|
55
|
-
- **Unique Identifiers**:
|
|
56
|
-
- Use `xxxCode` as the primary unique ID
|
|
57
|
-
- Generate unique codes using appropriate utility functions
|
|
58
|
-
- Maintain compatibility with different ID formats
|
|
59
|
-
|
|
60
|
-
## 3. Business Logic
|
|
61
|
-
|
|
62
|
-
### 3.1 Data Integrity
|
|
63
|
-
- **Immutable Fields**: Once created, most fields should not be updatable
|
|
64
|
-
- **Unique Identifiers**: Use consistent patterns for generating unique codes
|
|
65
|
-
- **Timestamps**: Use `Date.now()` for timestamps
|
|
66
|
-
|
|
67
|
-
### 3.2 Separation of Concerns
|
|
68
|
-
- **Data Models**: Should only contain data structure and basic validation
|
|
69
|
-
- **Repository Logic**: Should be implemented in the application layer
|
|
70
|
-
- **Business Logic**: Should be implemented in the application layer
|
|
71
|
-
|
|
72
|
-
## 4. Testing
|
|
73
|
-
|
|
74
|
-
### 4.1 Test Patterns
|
|
75
|
-
- Use Vitest for unit testing
|
|
76
|
-
- Place test files next to the corresponding model files
|
|
77
|
-
- Use descriptive test names
|
|
78
|
-
- Set test values to match field names (e.g., `myCode: 'myCode'`)
|
|
79
|
-
- Test both success and failure cases
|
|
80
|
-
|
|
81
|
-
### 4.2 Test Coverage
|
|
82
|
-
- Test model creation
|
|
83
|
-
- Test field validation
|
|
84
|
-
- Test update functionality
|
|
85
|
-
- Test edge cases
|
|
86
|
-
|
|
87
|
-
## 5. Build Process
|
|
88
|
-
|
|
89
|
-
### 5.1 TypeScript Configuration
|
|
90
|
-
- Use `tsconfig.json` for TypeScript configuration
|
|
91
|
-
- Generate declaration files (`*.d.ts`) for type hints
|
|
92
|
-
- Use appropriate plugins to generate declaration files during build
|
|
93
|
-
|
|
94
|
-
### 5.2 Package Configuration
|
|
95
|
-
- Configure `package.json` exports for different module formats
|
|
96
|
-
- Include proper type definitions in exports
|
|
97
|
-
- Use `pnpm` for package management
|
|
98
|
-
|
|
99
|
-
### 5.3 Build Output File Extensions
|
|
100
|
-
- **ESM**: `.esm.js` (ECMAScript Module)
|
|
101
|
-
- **CJS**: `.cjs` (CommonJS Module)
|
|
102
|
-
- **UMD**: `.umd.js` (Universal Module Definition)
|
|
103
|
-
- **IIFE**: `.iife.js` (Immediately Invoked Function Expression)
|
|
104
|
-
|
|
105
|
-
Example file names for a project named "project-name":
|
|
106
|
-
- `project-name.esm.js`
|
|
107
|
-
- `project-name.cjs`
|
|
108
|
-
- `project-name.umd.js`
|
|
109
|
-
- `project-name.iife.js`
|
|
110
|
-
|
|
111
|
-
## 6. Dependency Management
|
|
112
|
-
|
|
113
|
-
### 6.1 External Dependencies
|
|
114
|
-
- Use shared utility packages for common functionality
|
|
115
|
-
- Import utilities directly from packages
|
|
116
|
-
|
|
117
|
-
### 6.2 Internal Dependencies
|
|
118
|
-
- Use relative paths for internal imports
|
|
119
|
-
- Import constants from `../../constants`
|
|
120
|
-
- Organize imports logically
|
|
121
|
-
|
|
122
|
-
## 7. Constants
|
|
123
|
-
|
|
124
|
-
### 7.1 Constant Organization
|
|
125
|
-
- Place all constants in `lib/constants/` directory
|
|
126
|
-
- Group constants by domain
|
|
127
|
-
- Export constants from a central index file
|
|
128
|
-
|
|
129
|
-
### 7.2 Constant Usage
|
|
130
|
-
- Use constants instead of hardcoded strings
|
|
131
|
-
- Maintain consistent naming conventions for constants
|
|
132
|
-
|
|
133
|
-
Example:
|
|
134
|
-
```typescript
|
|
135
|
-
// Instead of using hardcoded strings:
|
|
136
|
-
if (status === 'active') {
|
|
137
|
-
// logic
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Use constants:
|
|
141
|
-
const STATUS = {
|
|
142
|
-
ACTIVE: 'active',
|
|
143
|
-
INACTIVE: 'inactive',
|
|
144
|
-
PENDING: 'pending'
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (status === STATUS.ACTIVE) {
|
|
148
|
-
// logic
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## 8. Error Handling
|
|
153
|
-
|
|
154
|
-
### 8.1 Validation
|
|
155
|
-
- Implement validation logic in model classes
|
|
156
|
-
- Use consistent patterns for indicating invalid models
|
|
157
|
-
- Use `isValid` property for model validation
|
|
158
|
-
- Return null from `init()` method for invalid models
|
|
159
|
-
|
|
160
|
-
### 8.2 Error Reporting
|
|
161
|
-
- Use descriptive error messages
|
|
162
|
-
- Log errors appropriately
|
|
163
|
-
- Handle edge cases gracefully
|
|
164
|
-
|
|
165
|
-
## 9. Performance
|
|
166
|
-
|
|
167
|
-
### 9.1 Code Optimization
|
|
168
|
-
- Use efficient algorithms
|
|
169
|
-
- Avoid unnecessary computations
|
|
170
|
-
- Use proper data structures
|
|
171
|
-
|
|
172
|
-
### 9.2 Build Optimization
|
|
173
|
-
- Use Vite for fast builds
|
|
174
|
-
- Configure build options for different module formats
|
|
175
|
-
- Generate optimized bundles
|
|
176
|
-
|
|
177
|
-
## 10. Documentation
|
|
178
|
-
|
|
179
|
-
### 10.1 Code Comments
|
|
180
|
-
- Add comments for complex logic
|
|
181
|
-
- Document public methods and properties
|
|
182
|
-
- Explain design decisions
|
|
183
|
-
|
|
184
|
-
### 10.2 Project Documentation
|
|
185
|
-
- Maintain this best practices document
|
|
186
|
-
- Update documentation when adding new features
|
|
187
|
-
- Document breaking changes
|
|
188
|
-
|
|
189
|
-
## 11. Build Tool Migration (Optional)
|
|
190
|
-
|
|
191
|
-
This section is only necessary for projects with existing Webpack, Gulp, or Mocha setups. If you're starting a new project, you can skip this section and directly use Vite and Vitest.
|
|
192
|
-
|
|
193
|
-
### 11.1 Considerations for Migration
|
|
194
|
-
|
|
195
|
-
#### Key Steps
|
|
196
|
-
- Update package.json to remove Webpack, Gulp, and Mocha dependencies
|
|
197
|
-
- Add Vite, Vitest, and related plugin dependencies
|
|
198
|
-
- Update scripts to use Vite for building and Vitest for testing
|
|
199
|
-
- Configure build output formats and type definitions
|
|
200
|
-
- Remove Webpack and Gulp configuration files
|
|
201
|
-
- Verify the migration works correctly
|
|
202
|
-
|
|
203
|
-
#### Benefits of Migrating to Vite and Vitest
|
|
204
|
-
- Faster build times compared to Webpack
|
|
205
|
-
- Modern, actively maintained tooling ecosystem
|
|
206
|
-
- Simplified configuration compared to Webpack
|
|
207
|
-
- Better TypeScript support
|
|
208
|
-
- Integrated testing with Vitest
|
|
209
|
-
- Consistency across Questwork projects
|
|
210
|
-
|
|
211
|
-
### 11.2 Core Configuration Elements
|
|
212
|
-
|
|
213
|
-
When setting up Vite and Vitest, ensure to include:
|
|
214
|
-
- Build configuration for multiple output formats (ESM, CJS, UMD, IIFE)
|
|
215
|
-
- Type declaration file generation
|
|
216
|
-
- Test configuration with appropriate environment setup
|
|
217
|
-
- Proper external dependency handling
|
|
@@ -1,321 +0,0 @@
|
|
|
1
|
-
# Building a JavaScript + TypeScript Library
|
|
2
|
-
|
|
3
|
-
This guide outlines the best practices for building a library that supports both JavaScript and TypeScript, based on the approaches used in the `qw.q.utilities` and `qw.q.ecoffice.model` projects.
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
1. [Project Setup](#project-setup)
|
|
8
|
-
2. [Code Structure](#code-structure)
|
|
9
|
-
3. [TypeScript Configuration](#typescript-configuration)
|
|
10
|
-
4. [Build Process](#build-process)
|
|
11
|
-
5. [Package Configuration](#package-configuration)
|
|
12
|
-
6. [Testing](#testing)
|
|
13
|
-
7. [Publishing](#publishing)
|
|
14
|
-
8. [Best Practices Reference](#best-practices-reference)
|
|
15
|
-
|
|
16
|
-
## 1. Project Setup
|
|
17
|
-
|
|
18
|
-
### 1.1 Initialize Project
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
# Create project directory
|
|
22
|
-
mkdir my-library
|
|
23
|
-
cd my-library
|
|
24
|
-
|
|
25
|
-
# Initialize with pnpm
|
|
26
|
-
pnpm init
|
|
27
|
-
|
|
28
|
-
# Install dependencies
|
|
29
|
-
pnpm add -D typescript vite vitest vite-plugin-dts
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### 1.2 Directory Structure
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
my-library/
|
|
36
|
-
├── lib/ # Source code
|
|
37
|
-
│ ├── helpers/ # Utility functions
|
|
38
|
-
│ ├── models/ # Data models
|
|
39
|
-
│ ├── index.ts # Main entry point
|
|
40
|
-
├── dist/ # Build output
|
|
41
|
-
├── package.json # Package configuration
|
|
42
|
-
├── tsconfig.json # TypeScript configuration
|
|
43
|
-
├── vite.config.js # Vite build configuration
|
|
44
|
-
├── vitest.config.js # Vitest configuration
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## 2. Code Structure
|
|
48
|
-
|
|
49
|
-
### 2.1 Main Entry Point
|
|
50
|
-
|
|
51
|
-
Create a TypeScript entry point that exports all modules:
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
// lib/index.ts
|
|
55
|
-
export * from './helpers/index.js';
|
|
56
|
-
export * from './models/index.js';
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### 2.2 Export Patterns
|
|
60
|
-
|
|
61
|
-
- Place all exports at the bottom of the file
|
|
62
|
-
- Separate named exports from type exports
|
|
63
|
-
- Use consistent naming conventions
|
|
64
|
-
|
|
65
|
-
## 3. TypeScript Configuration
|
|
66
|
-
|
|
67
|
-
### 3.1 tsconfig.json
|
|
68
|
-
|
|
69
|
-
```json
|
|
70
|
-
{
|
|
71
|
-
"compilerOptions": {
|
|
72
|
-
"target": "ES2020",
|
|
73
|
-
"module": "ESNext",
|
|
74
|
-
"lib": ["ES2020"],
|
|
75
|
-
"allowJs": true,
|
|
76
|
-
"checkJs": false,
|
|
77
|
-
"jsx": "preserve",
|
|
78
|
-
"declaration": true,
|
|
79
|
-
"declarationMap": true,
|
|
80
|
-
"sourceMap": true,
|
|
81
|
-
"outDir": "./dist",
|
|
82
|
-
"rootDir": "./lib",
|
|
83
|
-
"strict": false,
|
|
84
|
-
"moduleResolution": "node",
|
|
85
|
-
"allowSyntheticDefaultImports": true,
|
|
86
|
-
"esModuleInterop": true,
|
|
87
|
-
"skipLibCheck": true,
|
|
88
|
-
"forceConsistentCasingInFileNames": true
|
|
89
|
-
},
|
|
90
|
-
"include": [
|
|
91
|
-
"lib/**/*"
|
|
92
|
-
],
|
|
93
|
-
"exclude": [
|
|
94
|
-
"node_modules",
|
|
95
|
-
"dist"
|
|
96
|
-
]
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## 4. Build Process
|
|
101
|
-
|
|
102
|
-
### 4.1 Vite Configuration
|
|
103
|
-
|
|
104
|
-
```javascript
|
|
105
|
-
// vite.config.js
|
|
106
|
-
import { defineConfig } from 'vite';
|
|
107
|
-
import path from 'path';
|
|
108
|
-
import dts from 'vite-plugin-dts';
|
|
109
|
-
|
|
110
|
-
export default defineConfig({
|
|
111
|
-
plugins: [
|
|
112
|
-
dts({
|
|
113
|
-
include: ['lib/**/*.js', 'lib/**/*.ts'],
|
|
114
|
-
exclude: ['**/*.spec.js', '**/*.spec.ts'],
|
|
115
|
-
rollupTypes: true,
|
|
116
|
-
outDir: 'dist',
|
|
117
|
-
rootDir: 'lib',
|
|
118
|
-
}),
|
|
119
|
-
],
|
|
120
|
-
build: {
|
|
121
|
-
outDir: 'dist',
|
|
122
|
-
sourcemap: true,
|
|
123
|
-
lib: {
|
|
124
|
-
entry: path.resolve(__dirname, 'lib/index.ts'),
|
|
125
|
-
name: 'MyLibrary',
|
|
126
|
-
fileName: (format) => {
|
|
127
|
-
if (format === 'es') return 'my-library.esm.js';
|
|
128
|
-
if (format === 'cjs') return 'my-library.cjs';
|
|
129
|
-
if (format === 'umd') return 'my-library.umd.js';
|
|
130
|
-
return `my-library.${format}.js`;
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
rollupOptions: {
|
|
134
|
-
external: [], // Add external dependencies here
|
|
135
|
-
output: [
|
|
136
|
-
{
|
|
137
|
-
format: 'es',
|
|
138
|
-
generatedCode: 'es2015',
|
|
139
|
-
exports: 'named',
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
format: 'cjs',
|
|
143
|
-
exports: 'named',
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
format: 'umd',
|
|
147
|
-
name: 'MyLibrary',
|
|
148
|
-
exports: 'named',
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
format: 'iife',
|
|
152
|
-
name: 'MyLibrary',
|
|
153
|
-
exports: 'named',
|
|
154
|
-
},
|
|
155
|
-
],
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
test: {
|
|
159
|
-
environment: 'node',
|
|
160
|
-
coverage: {
|
|
161
|
-
reporter: ['text', 'html'],
|
|
162
|
-
},
|
|
163
|
-
globals: true,
|
|
164
|
-
setupFiles: ['lib/test.setup.js'],
|
|
165
|
-
mocha: {
|
|
166
|
-
ui: 'bdd',
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### 4.2 Build Scripts
|
|
173
|
-
|
|
174
|
-
Add build scripts to `package.json`:
|
|
175
|
-
|
|
176
|
-
```json
|
|
177
|
-
{
|
|
178
|
-
"scripts": {
|
|
179
|
-
"build": "vite build",
|
|
180
|
-
"test": "vitest run"
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
## 5. Package Configuration
|
|
186
|
-
|
|
187
|
-
### 5.1 package.json
|
|
188
|
-
|
|
189
|
-
```json
|
|
190
|
-
{
|
|
191
|
-
"name": "my-library",
|
|
192
|
-
"version": "1.0.0",
|
|
193
|
-
"description": "My JavaScript + TypeScript library",
|
|
194
|
-
"type": "module",
|
|
195
|
-
"exports": {
|
|
196
|
-
".": {
|
|
197
|
-
"require": "./dist/my-library.cjs",
|
|
198
|
-
"import": "./dist/my-library.esm.js",
|
|
199
|
-
"default": "./dist/my-library.umd.js",
|
|
200
|
-
"types": "./dist/my-library.d.ts"
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
"types": "./dist/my-library.d.ts",
|
|
204
|
-
"main": "./dist/my-library.cjs",
|
|
205
|
-
"module": "./dist/my-library.esm.js",
|
|
206
|
-
"unpkg": "./dist/my-library.umd.js",
|
|
207
|
-
"files": [
|
|
208
|
-
"dist"
|
|
209
|
-
],
|
|
210
|
-
"scripts": {
|
|
211
|
-
"build": "vite build",
|
|
212
|
-
"test": "vitest run"
|
|
213
|
-
},
|
|
214
|
-
"devDependencies": {
|
|
215
|
-
"typescript": "^5.9.3",
|
|
216
|
-
"vite": "^5.4.10",
|
|
217
|
-
"vite-plugin-dts": "^4.5.4",
|
|
218
|
-
"vitest": "^2.1.4"
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
## 6. Testing
|
|
224
|
-
|
|
225
|
-
### 6.1 Test Setup
|
|
226
|
-
|
|
227
|
-
Use Vitest for testing. Place test files next to the corresponding source files with `.spec.ts` extension:
|
|
228
|
-
|
|
229
|
-
```typescript
|
|
230
|
-
// lib/models/myModel.spec.ts
|
|
231
|
-
import { expect } from 'chai';
|
|
232
|
-
import { MyModel } from './myModel.js';
|
|
233
|
-
|
|
234
|
-
describe('MyModel', () => {
|
|
235
|
-
it('should create a valid model', () => {
|
|
236
|
-
const model = MyModel.init({ name: 'Test' });
|
|
237
|
-
expect(model.isValid).to.be.true;
|
|
238
|
-
});
|
|
239
|
-
});
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
## 7. Publishing
|
|
243
|
-
|
|
244
|
-
### 7.1 Build and Publish
|
|
245
|
-
|
|
246
|
-
```bash
|
|
247
|
-
# Build the library
|
|
248
|
-
pnpm run build
|
|
249
|
-
|
|
250
|
-
# Publish to npm
|
|
251
|
-
pnpm publish
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
## 8. Best Practices Reference
|
|
255
|
-
|
|
256
|
-
### 8.1 From qw.q.ecoffice.model/best_practices.md
|
|
257
|
-
|
|
258
|
-
#### 8.1.1 Build Output File Extensions
|
|
259
|
-
|
|
260
|
-
- **ESM**: `.esm.js` (ECMAScript Module)
|
|
261
|
-
- **CJS**: `.cjs` (CommonJS Module)
|
|
262
|
-
- **UMD**: `.umd.js` (Universal Module Definition)
|
|
263
|
-
- **IIFE**: `.iife.js` (Immediately Invoked Function Expression)
|
|
264
|
-
|
|
265
|
-
#### 8.1.2 TypeScript Configuration
|
|
266
|
-
- Use `tsconfig.json` for TypeScript configuration
|
|
267
|
-
- Generate declaration files (`*.d.ts`) for type hints
|
|
268
|
-
- Use `vite-plugin-dts` to generate declaration files during build
|
|
269
|
-
|
|
270
|
-
#### 8.1.3 Package Configuration
|
|
271
|
-
- Configure `package.json` exports for different module formats
|
|
272
|
-
- Include proper type definitions in exports
|
|
273
|
-
- Use `pnpm` for package management
|
|
274
|
-
|
|
275
|
-
#### 8.1.4 Code Structure
|
|
276
|
-
- **Models**: Place all data models in `lib/models/` directory
|
|
277
|
-
- **Helpers**: Place utility functions in `lib/helpers/` directory
|
|
278
|
-
- **Tests**: Place unit tests next to the corresponding model files with `.spec.ts` extension
|
|
279
|
-
|
|
280
|
-
#### 8.1.5 Testing
|
|
281
|
-
- Use Vitest for unit testing
|
|
282
|
-
- Place test files next to the corresponding model files
|
|
283
|
-
- Use descriptive test names
|
|
284
|
-
- Test both success and failure cases
|
|
285
|
-
|
|
286
|
-
## 9. Example Projects
|
|
287
|
-
|
|
288
|
-
- **qw.q.utilities**: A utility library with TypeScript support
|
|
289
|
-
- **qw.q.ecoffice.model**: A data model library with TypeScript support
|
|
290
|
-
|
|
291
|
-
## 10. Troubleshooting
|
|
292
|
-
|
|
293
|
-
### 10.1 Common Issues
|
|
294
|
-
|
|
295
|
-
#### 10.1.1 Circular Dependencies
|
|
296
|
-
|
|
297
|
-
- Avoid circular dependencies by importing directly from specific files instead of index files
|
|
298
|
-
- Use forward references when necessary
|
|
299
|
-
|
|
300
|
-
#### 10.1.2 Declaration File Generation
|
|
301
|
-
|
|
302
|
-
- Ensure `vite-plugin-dts` is properly configured
|
|
303
|
-
- Use a TypeScript entry point for better type analysis
|
|
304
|
-
- Check that all exports are properly typed
|
|
305
|
-
|
|
306
|
-
#### 10.1.3 Module Resolution
|
|
307
|
-
|
|
308
|
-
- Use proper file extensions in imports (e.g., `.js` for ESM even when importing from `.ts` files)
|
|
309
|
-
- Configure `package.json` exports correctly for different module formats
|
|
310
|
-
|
|
311
|
-
## 11. Conclusion
|
|
312
|
-
|
|
313
|
-
Building a JavaScript + TypeScript library requires careful configuration of TypeScript, Vite, and package.json. By following the best practices outlined in this guide and referencing the `qw.q.ecoffice.model` project, you can create a robust library that provides excellent type support for TypeScript users while remaining compatible with JavaScript users.
|
|
314
|
-
|
|
315
|
-
Key takeaways:
|
|
316
|
-
- Use TypeScript for the main entry point
|
|
317
|
-
- Configure Vite to generate multiple module formats
|
|
318
|
-
- Use `vite-plugin-dts` to generate declaration files
|
|
319
|
-
- Configure `package.json` exports for different module formats
|
|
320
|
-
- Include proper type definitions in the package configuration
|
|
321
|
-
- Test both TypeScript and JavaScript usage
|