Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb3d661e

Browse files
authored
feat: use a--bare flag to generate a template without too much boilerplate (#636)
Closes#112Closes#186Closes#300Closes#637
1 parentd4999b7 commitb3d661e

File tree

9 files changed

+128
-21
lines changed

9 files changed

+128
-21
lines changed

‎.github/workflows/ci.yml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ jobs:
4949
node-version:[18, 20, 22]
5050
os:[ubuntu-latest, windows-latest, macos-latest]
5151
verification-script:
52-
-pnpm --filter"\!*typescript*" build
53-
-pnpm --filter"*typescript*" build
54-
-pnpm --filter"*vitest*" test:unit
55-
-pnpm --filter"*eslint*" lint --no-fix --max-warnings=0
56-
-pnpm --filter"*prettier*" format --write --check
52+
-pnpm --filter'!*typescript*' build
53+
-pnpm --filter'*typescript*' build
54+
-pnpm --filter'*vitest*' test:unit
55+
-pnpm --filter'*eslint*' lint --no-fix --max-warnings=0
56+
-pnpm --filter'*prettier*' format --write --check
5757
# FIXME: it's failing now
58-
# - pnpm --filter"*with-tests*" test:unit
58+
# - pnpm --filter'*with-tests*' test:unit
5959
runs-on:${{ matrix.os }}
6060
continue-on-error:${{ matrix.os == 'windows-latest' }}
6161
env:
@@ -163,11 +163,12 @@ jobs:
163163

164164
-name:Run build script
165165
working-directory:./playground
166-
run:pnpm --filter"*${{ matrix.e2e-framework }}*" build
166+
run:pnpm --filter'*${{ matrix.e2e-framework }}*' build
167167

168168
-name:Run e2e test script
169169
working-directory:./playground
170-
run:pnpm --filter "*${{ matrix.e2e-framework }}*" --workspace-concurrency 1 test:e2e
170+
# bare templates can't pass e2e tests because their page structures don't match the example tests
171+
run:pnpm --filter '*${{ matrix.e2e-framework }}*' --filter '!*bare*' --workspace-concurrency 1 test:e2e
171172

172173
-name:Cypress component testing for projects without Vitest
173174
if:${{ contains(matrix.e2e-framework, 'cypress') }}

‎index.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import generateReadme from './utils/generateReadme'
1818
importgetCommandfrom'./utils/getCommand'
1919
importgetLanguagefrom'./utils/getLanguage'
2020
importrenderEslintfrom'./utils/renderEslint'
21+
importtrimBoilerplatefrom'./utils/trimBoilerplate'
2122

2223
functionisValidPackageName(projectName){
2324
return/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(projectName)
@@ -83,7 +84,9 @@ async function init() {
8384
// --playwright
8485
// --eslint
8586
// --eslint-with-prettier (only support prettier through eslint for simplicity)
86-
// --force (for force overwriting)
87+
// in addition to the feature flags, you can also pass the following options:
88+
// --bare (for a barebone template without example code)
89+
// --force (for force overwriting without confirming)
8790

8891
constargs=process.argv.slice(2)
8992

@@ -319,8 +322,8 @@ async function init() {
319322
packageName=projectName??defaultProjectName,
320323
shouldOverwrite=argv.force,
321324
needsJsx=argv.jsx,
322-
needsTypeScript=argv.ts||argv.typescript,
323-
needsRouter=argv.router||argv['vue-router'],
325+
needsTypeScript=(argv.ts||argv.typescript)asboolean,
326+
needsRouter=(argv.router||argv['vue-router'])asboolean,
324327
needsPinia=argv.pinia,
325328
needsVitest=argv.vitest||argv.tests,
326329
needsPrettier=argv['eslint-with-prettier'],
@@ -563,6 +566,25 @@ async function init() {
563566
)
564567
}
565568

569+
if(argv.bare){
570+
trimBoilerplate(root,{ needsTypeScript, needsRouter})
571+
render('bare/base')
572+
573+
// TODO: refactor the `render` utility to avoid this kind of manual mapping?
574+
if(needsTypeScript){
575+
render('bare/typescript')
576+
}
577+
if(needsVitest){
578+
render('bare/vitest')
579+
}
580+
if(needsCypressCT){
581+
render('bare/cypress-ct')
582+
}
583+
if(needsNightwatchCT){
584+
render('bare/nightwatch-ct')
585+
}
586+
}
587+
566588
// Instructions:
567589
// Supported package managers: pnpm > yarn > bun > npm
568590
constuserAgent=process.env.npm_config_user_agent??''

‎scripts/snapshot.mjs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ if (!/pnpm/.test(process.env.npm_config_user_agent ?? ''))
88
thrownewError("Please use pnpm ('pnpm run snapshot') to generate snapshots!")
99

1010
constfeatureFlags=[
11+
'bare',
1112
'typescript',
1213
'jsx',
1314
'router',
@@ -54,12 +55,7 @@ function fullCombination(arr) {
5455
}
5556

5657
letflagCombinations=fullCombination(featureFlags)
57-
flagCombinations.push(
58-
['default'],
59-
['router','pinia'],
60-
['eslint'],
61-
['eslint-with-prettier'],
62-
)
58+
flagCombinations.push(['default'],['bare','default'],['eslint'],['eslint-with-prettier'])
6359

6460
// `--with-tests` are equivalent of `--vitest --cypress`
6561
// Previously it means `--cypress` without `--vitest`.
@@ -85,10 +81,15 @@ for (const flags of flagCombinations) {
8581
}
8682

8783
// Filter out combinations that are not allowed
88-
flagCombinations=flagCombinations.filter(
89-
(combination)=>
90-
!featureFlagsDenylist.some((denylist)=>denylist.every((flag)=>combination.includes(flag))),
91-
)
84+
flagCombinations=flagCombinations
85+
.filter(
86+
(combination)=>
87+
!featureFlagsDenylist.some((denylist)=>
88+
denylist.every((flag)=>combination.includes(flag)),
89+
),
90+
)
91+
// `--bare` is a supplementary flag and should not be used alone
92+
.filter((combination)=>!(combination.length===1&&combination[0]==='bare'))
9293

9394
constbin=path.posix.relative('../playground/','../outfile.cjs')
9495

‎template/bare/base/src/App.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script setup></script>
2+
3+
<template>
4+
<h1>Hello World</h1>
5+
</template>
6+
7+
<style scoped></style>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
importAppfrom'../App.vue'
2+
3+
describe('App',()=>{
4+
it('mounts and renders properly',()=>{
5+
cy.mount(App)
6+
cy.get('h1').should('contain','Hello World')
7+
})
8+
})
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
describe('App',function(){
2+
before((browser)=>{
3+
browser.init()
4+
})
5+
6+
it('mounts and renders properly',asyncfunction(){
7+
constappComponent=awaitbrowser.mountComponent('/src/App.vue');
8+
9+
browser.expect.element(appComponent).to.be.present;
10+
browser.expect.element('h1').text.to.contain('Hello World');
11+
})
12+
13+
after((browser)=>browser.end())
14+
})

‎template/bare/typescript/src/App.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script setup lang="ts"></script>
2+
3+
<template>
4+
<h1>Hello World</h1>
5+
</template>
6+
7+
<style scoped></style>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import{describe,it,expect}from'vitest'
2+
3+
import{mount}from'@vue/test-utils'
4+
importAppfrom'../App.vue'
5+
6+
describe('App',()=>{
7+
it('mounts renders properly',()=>{
8+
constwrapper=mount(App)
9+
expect(wrapper.text()).toContain('Hello World')
10+
})
11+
})

‎utils/trimBoilerplate.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import*asfsfrom'node:fs'
2+
import*aspathfrom'path'
3+
4+
functionreplaceContent(filepath:string,replacer:(content:string)=>string){
5+
constcontent=fs.readFileSync(filepath,'utf8')
6+
fs.writeFileSync(filepath,replacer(content))
7+
}
8+
9+
exportdefaultfunctiontrimBoilerplate(rootDir:string,features:Record<string,boolean>){
10+
constisTs=features.needsTypeScript
11+
constsrcDir=path.resolve(rootDir,'src')
12+
13+
for(constfilenameoffs.readdirSync(srcDir)){
14+
// Keep `main.js/ts`, `router`, and `stores` directories
15+
// `App.vue` would be re-rendered in the next step
16+
if(['main.js','main.ts','router','stores'].includes(filename)){
17+
continue
18+
}
19+
constfullpath=path.resolve(srcDir,filename)
20+
fs.rmSync(fullpath,{recursive:true})
21+
}
22+
23+
// Remove CSS import in the entry file
24+
constentryPath=path.resolve(rootDir,isTs ?'src/main.ts' :'src/main.js')
25+
replaceContent(entryPath,(content)=>content.replace("import './assets/main.css'\n\n",''))
26+
27+
// If `router` feature is selected, use an empty router configuration
28+
if(features.needsRouter){
29+
constrouterEntry=path.resolve(srcDir,isTs ?'router/index.ts' :'router/index.js')
30+
replaceContent(routerEntry,(content)=>
31+
content
32+
.replace(`import HomeView from '../views/HomeView.vue'\n`,'')
33+
.replace(/routes:\s*\[[\s\S]*?\],/,'routes: [],'),
34+
)
35+
}
36+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp