From 113eb65e6dfc856504e91d39b61c059e8b0b9a3c Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Wed, 26 Jun 2019 18:25:47 +0800 Subject: [PATCH] feat: add `transformScript` to GeneratorAPI (#4188) (cherry picked from commit 5460ca498ff676a640ac52f85cc270ee0592527e) --- packages/@vue/cli/__tests__/Generator.spec.js | 33 +++++++++++++++++++ packages/@vue/cli/lib/GeneratorAPI.js | 17 ++++++++++ packages/@vue/cli/package.json | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/packages/@vue/cli/__tests__/Generator.spec.js b/packages/@vue/cli/__tests__/Generator.spec.js index de0f563516..157546d9b1 100644 --- a/packages/@vue/cli/__tests__/Generator.spec.js +++ b/packages/@vue/cli/__tests__/Generator.spec.js @@ -727,3 +727,36 @@ test('generate a JS-Only value from a string', async () => { expect(generator.pkg).toHaveProperty('testScript') expect(typeof generator.pkg.testScript).toBe('function') }) + +test('run a codemod on the entry file', async () => { + // A test codemod that tranforms `new Vue` to `new TestVue` + const codemod = (fileInfo, api) => { + const j = api.jscodeshift + return j(fileInfo.source) + .find(j.NewExpression, { + callee: { name: 'Vue' }, + arguments: [{ type: 'ObjectExpression' }] + }) + .replaceWith(({ node }) => { + node.callee.name = 'TestVue' + return node + }) + .toSource() + } + + const generator = new Generator('/', { plugins: [ + { + id: 'test', + apply: api => { + api.render({ + 'main.js': path.join(templateDir, 'entry.js') + }) + + api.transformScript('main.js', codemod) + } + } + ] }) + + await generator.generate() + expect(fs.readFileSync('/main.js', 'utf-8')).toMatch(/new TestVue/) +}) diff --git a/packages/@vue/cli/lib/GeneratorAPI.js b/packages/@vue/cli/lib/GeneratorAPI.js index 9aec3478e6..cc0f87077e 100644 --- a/packages/@vue/cli/lib/GeneratorAPI.js +++ b/packages/@vue/cli/lib/GeneratorAPI.js @@ -6,6 +6,7 @@ const resolve = require('resolve') const { isBinaryFileSync } = require('isbinaryfile') const semver = require('semver') const mergeDeps = require('./util/mergeDeps') +const runCodemod = require('./util/runCodemod') const stringifyJS = require('./util/stringifyJS') const ConfigTransform = require('./ConfigTransform') const { getPluginLink, toShortPluginId, loadModule } = require('@vue/cli-shared-utils') @@ -300,6 +301,22 @@ class GeneratorAPI { return fn } + /** + * Run codemod on a script file or the script part of a .vue file + * @param {string} file the path to the file to transform + * @param {Codemod} codemod the codemod module to run + * @param {object} options additional options for the codemod + */ + transformScript (file, codemod, options) { + this._injectFileMiddleware(files => { + files[file] = runCodemod( + codemod, + { path: this.resolve(file), source: files[file] }, + options + ) + }) + } + /** * Add import statements to a file. */ diff --git a/packages/@vue/cli/package.json b/packages/@vue/cli/package.json index e6b92a22e5..00b4fdae8f 100644 --- a/packages/@vue/cli/package.json +++ b/packages/@vue/cli/package.json @@ -56,7 +56,7 @@ "shortid": "^2.2.11", "slash": "^2.0.0", "validate-npm-package-name": "^3.0.0", - "vue-jscodeshift-adapter": "2.0.2", + "vue-jscodeshift-adapter": "^2.0.2", "yaml-front-matter": "^3.4.1" }, "engines": {