Skip to content

Commit 27af417

Browse files
李文富yyx990803
李文富
authored andcommitted
add skipInterpolation option to specify files that should skip rendering (vuejs#225)
* add skipInterpolation option to specify files that should not be rendered with handlebars * add skipInterpolation description
1 parent 1795cc1 commit 27af417

File tree

6 files changed

+62
-17
lines changed

6 files changed

+62
-17
lines changed

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,16 @@ Files under `test` will only be generated if the user answered yes to the prompt
163163

164164
Note that the `dot` option for minimatch is set to `true` so glob patterns would also match dotfiles by default.
165165

166+
#### Skip rendering
167+
168+
The `skipInterpolation` field in the metadata file should be a [minimatch glob pattern](https://github.com/isaacs/minimatch). The files matched should skip rendering. Example:
169+
170+
``` json
171+
{
172+
"skipInterpolation": "src/**/*.vue"
173+
}
174+
```
175+
166176
#### Additional data available in meta.{js,json}
167177

168178
- `destDirName` - destination directory name

lib/generate.js

+23-16
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var Handlebars = require('handlebars')
33
var async = require('async')
44
var render = require('consolidate').handlebars.render
55
var path = require('path')
6+
var match = require('minimatch')
67
var getOptions = require('./options')
78
var ask = require('./ask')
89
var filter = require('./filter')
@@ -43,7 +44,7 @@ module.exports = function generate (name, src, dest, done) {
4344
metalsmith
4445
.use(askQuestions(opts.prompts))
4546
.use(filterFiles(opts.filters))
46-
.use(renderTemplateFiles)
47+
.use(renderTemplateFiles(opts.skipInterpolation))
4748
.clean(false)
4849
.source('.') // start from template root instead of `./src` which is Metalsmith's default for `source`
4950
.destination(dest)
@@ -89,21 +90,27 @@ function filterFiles (filters) {
8990
* @param {Function} done
9091
*/
9192

92-
function renderTemplateFiles (files, metalsmith, done) {
93-
var keys = Object.keys(files)
94-
var metalsmithMetadata = metalsmith.metadata()
95-
async.each(keys, function (file, next) {
96-
var str = files[file].contents.toString()
97-
// do not attempt to render files that do not have mustaches
98-
if (!/{{([^{}]+)}}/g.test(str)) {
99-
return next()
100-
}
101-
render(str, metalsmithMetadata, function (err, res) {
102-
if (err) return next(err)
103-
files[file].contents = new Buffer(res)
104-
next()
105-
})
106-
}, done)
93+
function renderTemplateFiles (skipInterpolation) {
94+
return function (files, metalsmith, done) {
95+
var keys = Object.keys(files)
96+
var metalsmithMetadata = metalsmith.metadata()
97+
async.each(keys, function (file, next) {
98+
// skipping files with skipInterpolation option
99+
if (skipInterpolation && match(file, skipInterpolation, { dot: true })) {
100+
return next()
101+
}
102+
var str = files[file].contents.toString()
103+
// do not attempt to render files that do not have mustaches
104+
if (!/{{([^{}]+)}}/g.test(str)) {
105+
return next()
106+
}
107+
render(str, metalsmithMetadata, function (err, res) {
108+
if (err) return next(err)
109+
files[file].contents = new Buffer(res)
110+
next()
111+
})
112+
}, done)
113+
}
107114
}
108115

109116
/**

test/e2e/mock-template-repo/meta.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@
3838
"filters": {
3939
"src/*.js": "pick === 'yes'",
4040
"**/*.vue": "pick === 'no'"
41-
}
41+
},
42+
"skipInterpolation": "src/*-{one,two}.vue"
4243
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<template>one: {{description}}</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<template>two: {{description}}</template>

test/e2e/test.js

+25
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,31 @@ describe('vue-cli', () => {
130130
})
131131
})
132132

133+
it('avoid rendering files that match skipInterpolation option', done => {
134+
monkeyPatchInquirer(answers)
135+
const binFilePath = `${MOCK_TEMPLATE_REPO_PATH}/template/bin.file`
136+
const wstream = fs.createWriteStream(binFilePath)
137+
wstream.write(crypto.randomBytes(100))
138+
wstream.end()
139+
140+
generate('test', MOCK_TEMPLATE_REPO_PATH, MOCK_TEMPLATE_BUILD_PATH, err => {
141+
if (err) done(err)
142+
143+
const originalVueFileOne = fs.readFileSync(`${MOCK_TEMPLATE_REPO_PATH}/template/src/skip-one.vue`, 'utf8')
144+
const originalVueFileTwo = fs.readFileSync(`${MOCK_TEMPLATE_REPO_PATH}/template/src/skip-two.vue`, 'utf8')
145+
const generatedVueFileOne = fs.readFileSync(`${MOCK_TEMPLATE_BUILD_PATH}/src/skip-one.vue`, 'utf8')
146+
const generatedVueFileTwo = fs.readFileSync(`${MOCK_TEMPLATE_BUILD_PATH}/src/skip-two.vue`, 'utf8')
147+
148+
expect(originalVueFileOne).to.equal(generatedVueFileOne)
149+
expect(originalVueFileTwo).to.equal(generatedVueFileTwo)
150+
expect(exists(binFilePath)).to.equal(true)
151+
expect(exists(`${MOCK_TEMPLATE_BUILD_PATH}/bin.file`)).to.equal(true)
152+
rm(binFilePath)
153+
154+
done()
155+
})
156+
})
157+
133158
it('validate input value', done => {
134159
// deep copy
135160
var invalidName = extend({}, answers, {name: 'INVALID-NAME'})

0 commit comments

Comments
 (0)