From a68455c3e267a2821410a83416975bd606fd2d39 Mon Sep 17 00:00:00 2001 From: Rahul Kadyan Date: Wed, 2 May 2018 10:56:28 +0530 Subject: [PATCH] feat: Convert styles to import statements --- .eslintrc.json | 3 +- package.json | 2 +- src/delegate.js | 174 ------------------------------------------ src/index.js | 169 +++++++++++++++++++++++++++++++++++++++- src/simple.js | 52 ------------- test/baseline.spec.js | 11 +-- test/setup/index.js | 6 +- yarn.lock | 6 +- 8 files changed, 177 insertions(+), 246 deletions(-) delete mode 100644 src/delegate.js delete mode 100644 src/simple.js diff --git a/.eslintrc.json b/.eslintrc.json index 256f100..a388ce7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,7 +1,8 @@ { "env": { "browser": true, - "node": true + "node": true, + "jest": true }, "globals": { "Promise": true diff --git a/package.json b/package.json index 44a5a36..22b28b6 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "homepage": "https://github.com/znck/rollup-plugin-vue#readme", "dependencies": { "@babel/runtime": "^7.0.0-beta.39", - "@vue/component-compiler": "^3.1.0", + "@vue/component-compiler": "3.1.1", "@vue/component-compiler-utils": "^1.2.1", "debug": "^2.6.0", "hash-sum": "^1.0.2", diff --git a/src/delegate.js b/src/delegate.js deleted file mode 100644 index 6c5b74c..0000000 --- a/src/delegate.js +++ /dev/null @@ -1,174 +0,0 @@ -import { - createVueFilter, - isVuePartRequest, - createVuePartRequest, - parseVuePartRequest, - resolveVuePart -} from './utils' -import * as path from 'path' -import { parse } from '@vue/component-compiler-utils' -import { createDefaultCompiler, assemble } from '@vue/component-compiler' -import hash from 'hash-sum' -import { relative } from 'path' - -export default function vue(opts = {}) { - const isVue = createVueFilter(opts.include, opts.exclude) - const isProduction = process.env.NODE_ENV === 'production' - const compiler = createDefaultCompiler(opts.compiler) - createVuePartRequest.defaultLang = { - ...createVuePartRequest.defaultLang, - ...opts.defaultLang - } - - const blacklisted = new Set(opts.blacklistCustomBlocks || []) - - delete opts.include - delete opts.exclude - - const descriptors = new WeakMap() - - function compileTemplate(id, { functional }, source) { - const { template } = compiler.compileToDescriptor( - id.filename, - `` - ) - - if (template.errors && template.errors.length) { - console.error( - '> Errors: ' + - relative(process.cwd(), id.filename) + - '\n' + - template.errors.map(it => ' - ' + it).join('\n') - ) - } - - if (template.tips && template.tips.length) { - console.log( - '> Tips: ' + - relative(process.cwd(), id.filename) + - '\n' + - template.tips.map(it => ' - ' + it).join('\n') - ) - } - - return `${template.code}\n export { render, staticRenderFns }` - } - - return { - name: 'vue.delegate', - - resolveId(id) { - if (isVuePartRequest(id)) { - const ref = parseVuePartRequest(id) - const element = resolveVuePart(descriptors, ref) - - if (element.src) - return path.resolve(path.dirname(ref.filename), element.src) - - return id - } - }, - - load(id) { - if (!isVuePartRequest(id)) return - - id = parseVuePartRequest(id) - - return resolveVuePart(descriptors, id).content - }, - - async transform(source, filename) { - if (isVue(filename)) { - const descriptor = (descriptors[filename] = parse({ - filename, - source, - needMap: true - })) - const scopeId = - 'data-v-' + - (isProduction - ? hash(path.basename(filename) + source) - : hash(filename + source)) - const input = { - scopeId, - styles: [], - customBlocks: [] - } - - if (descriptor.template) { - input.template = { - code: ` - import * as template from '${createVuePartRequest( - filename, - descriptor.template.lang, - 'template' - )}' - var render = template.render - var staticRenderFns = template.staticRenderFns - `, - functional: 'functional' in descriptor.template.attrs - } - } - - if (descriptor.script) { - input.script = { - code: ` - export * from '${createVuePartRequest( - filename, - descriptor.script.lang, - 'script' - )}' - import script from '${createVuePartRequest( - filename, - descriptor.script.lang, - 'script' - )}' - export default script - ` - } - } - - const result = assemble(compiler, filename, input, opts) - - descriptor.customBlocks.forEach((block, index) => { - if (blacklisted.has(block.type)) return - result.code += - '\n' + - `export * from '${createVuePartRequest( - filename, - block.attrs.lang || - createVuePartRequest.defaultLang[block.type] || - block.type, - 'customBlocks', - index - )}'` - }) - - return result - } - - if (isVuePartRequest(filename)) { - const id = parseVuePartRequest(filename) - const element = resolveVuePart(descriptors, id) - - if (id.meta.type === 'styles') { - const { styles } = compiler.compileToDescriptor( - id.filename, - `` - ) - - return styles[0] - } else if (id.meta.type === 'template') { - return compileTemplate(id, element, source) - } - } - } - } -} diff --git a/src/index.js b/src/index.js index 6f7183e..0aa4f60 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,167 @@ -import inline from './simple' -import delegate from './delegate' +import { + createVueFilter, + isVuePartRequest, + createVuePartRequest, + parseVuePartRequest, + resolveVuePart +} from './utils' +import * as path from 'path' +import { parse } from '@vue/component-compiler-utils' +import { createDefaultCompiler, assemble } from '@vue/component-compiler' +import hash from 'hash-sum' +import { relative } from 'path' -inline.delegate = delegate +export default function vue(opts = {}) { + const isVue = createVueFilter(opts.include, opts.exclude) + const isProduction = process.env.NODE_ENV === 'production' + createVuePartRequest.defaultLang = { + ...createVuePartRequest.defaultLang, + ...opts.defaultLang + } -export default inline + const shouldExtractCss = opts.css === false + const blacklisted = new Set(opts.blacklistCustomBlocks || ['*']) + const whitelisted = new Set(opts.blacklistCustomBlocks || []) + + const isAllowed = any => + (!blacklisted.has('*') || !blacklisted.has(any)) && + (whitelisted.has('*') || whitelisted.has(any)) + + delete opts.css + delete opts.blacklistCustomBlocks + delete opts.defaultLang + delete opts.include + delete opts.exclude + + const compiler = createDefaultCompiler(opts) + const descriptors = new WeakMap() + + return { + name: 'vue.delegate', + + resolveId(id) { + if (isVuePartRequest(id)) { + const ref = parseVuePartRequest(id) + const element = resolveVuePart(descriptors, ref) + + if (element.src && ref.meta.type !== 'styles') + return path.resolve(path.dirname(ref.filename), element.src) + + return id + } + }, + + load(id) { + if (!isVuePartRequest(id)) return + + id = parseVuePartRequest(id) + const element = resolveVuePart(descriptors, id) + + return element.code || element.content + }, + + async transform(source, filename) { + if (isVue(filename)) { + const descriptor = (descriptors[filename] = parse({ + filename, + source, + needMap: true + })) + const scopeId = + 'data-v-' + + (isProduction + ? hash(path.basename(filename) + source) + : hash(filename + source)) + const input = { + scopeId, + styles: descriptor.styles.map(style => + compiler.compileStyle(filename, scopeId, style) + ), + customBlocks: [] + } + + if (descriptor.template) { + input.template = compiler.compileTemplate( + filename, + descriptor.template + ) + + if (input.template.errors && input.template.errors.length) { + console.error( + '> Errors: ' + + relative(process.cwd(), filename) + + '\n' + + input.template.errors.map(it => ' - ' + it).join('\n') + ) + } + + if (input.template.tips && input.template.tips.length) { + console.log( + '> Tips: ' + + relative(process.cwd(), filename) + + '\n' + + input.template.tips.map(it => ' - ' + it).join('\n') + ) + } + } + + input.script = descriptor.script + ? { + code: ` + export * from '${createVuePartRequest( + filename, + descriptor.script.lang, + 'script' + )}' + import script from '${createVuePartRequest( + filename, + descriptor.script.lang, + 'script' + )}' + export default script + ` + } + : { code: '' } + + if (shouldExtractCss) { + input.styles = input.styles + .map((style, index) => { + descriptor.styles[index].code = style.code + + input.script.code += + '\n' + + `import '${createVuePartRequest( + filename, + 'css', + 'styles', + index + )}'` + + if (style.module) { + return { ...style, code: '' } + } + }) + .filter(Boolean) + } + + const result = assemble(compiler, filename, input, opts) + + descriptor.customBlocks.forEach((block, index) => { + if (!isAllowed(block.type)) return + result.code += + '\n' + + `export * from '${createVuePartRequest( + filename, + block.attrs.lang || + createVuePartRequest.defaultLang[block.type] || + block.type, + 'customBlocks', + index + )}'` + }) + + return result + } + } + } +} diff --git a/src/simple.js b/src/simple.js deleted file mode 100644 index db7a23e..0000000 --- a/src/simple.js +++ /dev/null @@ -1,52 +0,0 @@ -import { createVueFilter } from './utils' -import { createDefaultCompiler, assemble } from '@vue/component-compiler' -import { relative } from 'path' - -export default function vue(opts = {}) { - const isVue = createVueFilter(opts.include, opts.exclude) - - delete opts.include - delete opts.exclude - - const compiler = createDefaultCompiler(opts) - - return { - name: 'vue', - - async transform(source, filename) { - if (!isVue(filename)) return - - const descriptor = compiler.compileToDescriptor(filename, source) - - if ( - descriptor.template && - descriptor.template.errors && - descriptor.template.errors.length - ) { - console.error( - '> Errors: ' + - relative(process.cwd(), filename) + - '\n' + - descriptor.template.errors.map(it => ' - ' + it).join('\n') - ) - } - - if ( - descriptor.template && - descriptor.template.tips && - descriptor.template.tips.length - ) { - console.log( - '> Tips: ' + - relative(process.cwd(), filename) + - '\n' + - descriptor.template.tips.map(it => ' - ' + it).join('\n') - ) - } - - const result = assemble(compiler, filename, descriptor) - - return result.code - } - } -} diff --git a/test/baseline.spec.js b/test/baseline.spec.js index 7d90d6b..2ed09f5 100644 --- a/test/baseline.spec.js +++ b/test/baseline.spec.js @@ -16,14 +16,10 @@ beforeAll(async () => { }) afterAll(async () => browser && (await browser.close())) -const testRunner = async (fixture, delegate) => { +const testRunner = async fixture => { const filename = join(__dirname, 'fixtures', fixture + '.vue') - const code = await build(filename, delegate) - const page = await open( - fixture + (delegate ? '-delegated' : ''), - browser, - code - ) + const code = await build(filename) + const page = await open(fixture, browser, code) expect(await page.$('#test')).toBeTruthy() expect( await page.evaluate(() => document.getElementById('test').textContent) @@ -39,5 +35,4 @@ const testRunner = async (fixture, delegate) => { } fixtures.forEach(fixture => { test(fixture, () => testRunner(fixture, false)) - // test(fixture + ' (delegated)', () => testRunner(fixture, true)) }) diff --git a/test/setup/index.js b/test/setup/index.js index 4fa6859..46c142c 100644 --- a/test/setup/index.js +++ b/test/setup/index.js @@ -30,8 +30,8 @@ const babelIt = babel({ const cache = {} -async function build(filename, delegate = false) { - const cacheKey = filename + delegate +async function build(filename) { + const cacheKey = filename if (cacheKey in cache) return cache[cacheKey] const input = filename + '__app.js' @@ -40,7 +40,7 @@ async function build(filename, delegate = false) { input, plugins: [ md(), - delegate ? vue.delegate(options) : vue(options), + vue(options), image(), nodeResolve(), inline( diff --git a/yarn.lock b/yarn.lock index b312bad..233a91a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -565,9 +565,9 @@ source-map "^0.5.6" vue-template-es2015-compiler "^1.6.0" -"@vue/component-compiler@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@vue/component-compiler/-/component-compiler-3.1.0.tgz#d80cf92d1049c346039de2954a7d655e559e35b6" +"@vue/component-compiler@3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@vue/component-compiler/-/component-compiler-3.1.1.tgz#8580b357e23cec391f113a1f51dbe6f1b71be66f" dependencies: "@vue/component-compiler-utils" "^1.2.1" clean-css "^4.1.11"