Skip to content
This repository has been archived by the owner on Jan 18, 2022. It is now read-only.

fix: Transform require in render function compiled from template #212

Merged
merged 1 commit into from Jun 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -7,6 +7,7 @@ output/
logs/
*.log
npm-debug.log*
docs/changelog.md

# Runtime data
pids
Expand Down
17 changes: 13 additions & 4 deletions package.json
Expand Up @@ -19,15 +19,20 @@
},
"standard-version": {
"scripts": {
"postchangelog": "yarn test && yarn docs && git add docs/"
"postchangelog": "yarn test && yarn build:docs && git add docs/"
}
},
"scripts": {
"prepublishOnly": "yarn build",
"prebuild": "yarn lint",
"build": "tsc",
"prebuild:docs": "cp CHANGELOG.md docs/changelog.md",
"build:docs": "vuepress build docs/",
"postbuild:docs": "rm docs/changelog.md",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 1",
"docs": "typedoc typings src/index.ts && touch docs/.nojekyll",
"predocs": "cp CHANGELOG.md docs/changelog.md",
"docs": "vuepress dev docs/",
"postdocs": "rm docs/CHANGELOG.md",
"lint": "prettier --no-semi --single-quote --write **/*.js **/*.vue !test/target/** !dist/**",
"release": "standard-version -a",
"pretest": "yarn build",
Expand All @@ -43,7 +48,6 @@
"@vue/component-compiler-utils": "^1.2.1",
"debug": "^2.6.0",
"hash-sum": "^1.0.2",
"postcss": "^6.0.22",
"querystring": "^0.2.0",
"rollup-pluginutils": "^2.0.1"
},
Expand All @@ -52,6 +56,7 @@
"@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.46",
"@babel/plugin-transform-runtime": "^7.0.0-beta.46",
"@babel/preset-env": "^7.0.0-beta.46",
"@types/debug": "^0.0.30",
"@types/jest": "^22.2.3",
"@types/node": "^10.0.4",
"@types/puppeteer": "^1.3.1",
Expand All @@ -62,20 +67,24 @@
"conventional-changelog": "^1.1.24",
"jest": "^22.4.2",
"node-sass": "^4.9.0",
"postcss": "^6.0.22",
"postcss-assets": "^5.0.0",
"prettier": "^1.12.1",
"pug": "^2.0.3",
"puppeteer": "^1.4.0",
"rollup": "^0.58.2",
"rollup-plugin-babel": "^4.0.0-beta.4",
"rollup-plugin-commonjs": "^9.1.3",
"rollup-plugin-css-only": "^0.4.0",
"rollup-plugin-image": "^1.0.2",
"rollup-plugin-md": "^0.0.7",
"rollup-plugin-node-resolve": "^3.3.0",
"rollup-plugin-replace": "^2.0.0",
"rollup-plugin-typescript": "^0.8.1",
"rollup-plugin-url": "^1.4.0",
"ts-jest": "^22.4.5",
"typescript": "^2.8.3",
"vue": "^2.5.16",
"vue-class-component": "^6.2.0",
"vue-template-compiler": "^2.5.16"
},
"peerDependencies": {
Expand Down
59 changes: 43 additions & 16 deletions src/index.ts
Expand Up @@ -3,7 +3,8 @@ import {
createVuePartRequest,
parseVuePartRequest,
resolveVuePart,
isVuePartRequest
isVuePartRequest,
transformRequireToImport
} from './utils'
import {
createDefaultCompiler,
Expand All @@ -13,26 +14,29 @@ import {
TemplateOptions,
StyleCompileResult
} from '@vue/component-compiler'
import {Plugin} from 'rollup'
import { Plugin } from 'rollup'
import * as path from 'path'
import {parse, SFCDescriptor, SFCBlock} from '@vue/component-compiler-utils'
import { parse, SFCDescriptor, SFCBlock } from '@vue/component-compiler-utils'
import debug from 'debug'

const hash = require('hash-sum')
const d = debug('rollup-plugin-vue')
const { version } = require('../package.json')

export interface VuePluginOptions {
/**
* Include files or directories.
* @default `'.vue'`
*/
include?: Array<string|RegExp> | string | RegExp
include?: Array<string | RegExp> | string | RegExp
/**
* Exclude files or directories.
* @default `undefined`
*/
exclude?: Array<string|RegExp> | string | RegExp
exclude?: Array<string | RegExp> | string | RegExp
/**
* Default language for blocks.
*
*
* @default `{}`
* @example
* ```js
Expand All @@ -41,7 +45,7 @@ export interface VuePluginOptions {
*/
defaultLang?: {
[key: string]: string
},
}
/**
* Exclude customBlocks for final build.
* @default `['*']`
Expand Down Expand Up @@ -99,7 +103,12 @@ export interface VuePluginOptions {
*/
export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
const isVue = createVueFilter(opts.include, opts.exclude)
const isProduction = process.env.NODE_ENV === 'production'
const isProduction =
process.env.NODE_ENV === 'production' || process.env.BUILD === 'production'

d('Version ' + version)
d(`Build environment: ${isProduction ? 'production' : 'development'}`)
d(`Build target: ${process.env.VUE_ENV || 'browser'}`)

createVuePartRequest.defaultLang = {
...createVuePartRequest.defaultLang,
Expand All @@ -121,9 +130,23 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
delete opts.include
delete opts.exclude

opts.template = {
transformAssetUrls: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
},
...opts.template
} as any
if (opts.template && typeof opts.template.isProduction === 'undefined') {
opts.template.isProduction = isProduction
}
const compiler = createDefaultCompiler(opts)
const descriptors = new Map<string, SFCDescriptor>()

if (opts.css === false) d('Running in CSS extract mode')

return {
name: 'VuePlugin',

Expand Down Expand Up @@ -154,7 +177,7 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
const element = resolveVuePart(descriptors, request)

return 'code' in element
? (element as any).code as string // .code is set when extract styles is used. { css: false }
? ((element as any).code as string) // .code is set when extract styles is used. { css: false }
: element.content
},

Expand Down Expand Up @@ -186,6 +209,10 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
descriptor.template
)

input.template.code = transformRequireToImport(
input.template.code
)

if (input.template.errors && input.template.errors.length) {
input.template.errors.map((error: Error) => this.error(error))
}
Expand All @@ -197,7 +224,7 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {

input.script = descriptor.script
? {
code: `
code: `
export * from '${createVuePartRequest(
filename,
descriptor.script.lang || 'js',
Expand All @@ -210,13 +237,13 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
)}'
export default script
`
}
: {code: ''}
}
: { code: '' }

if (shouldExtractCss) {
input.styles = input.styles
.map((style: StyleCompileResult, index: number) => {
(descriptor.styles[index] as any).code = style.code
;(descriptor.styles[index] as any).code = style.code

input.script.code +=
'\n' +
Expand All @@ -228,7 +255,7 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
)}'`

if (style.module || descriptor.styles[index].scoped) {
return {...style, code: ''}
return { ...style, code: '' }
}
})
.filter(Boolean)
Expand All @@ -243,8 +270,8 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
`export * from '${createVuePartRequest(
filename,
block.attrs.lang ||
createVuePartRequest.defaultLang[block.type] ||
block.type,
createVuePartRequest.defaultLang[block.type] ||
block.type,
'customBlocks',
index
)}'`
Expand Down
16 changes: 16 additions & 0 deletions src/utils.ts
Expand Up @@ -123,3 +123,19 @@ export function resolveVuePart(

return block
}

export function transformRequireToImport(code: string): string {
const imports: { [key: string]: string } = {}
let strImports = ''

code = code.replace(/require\(("(?:[^"\\]|\\.)+"|'(?:[^'\\]|\\.)+')\)/g, (_, name): any => {
if (!(name in imports)) {
imports[name] = `__$_require_${name.replace(/[^a-z0-9]/g, '_').replace(/_{2,}/g, '_').replace(/^_|_$/g, '')}__`
strImports += 'import ' + imports[name] + ' from ' + name + '\n'
}

return imports[name]
})

return strImports + code
}
Empty file added test/assertions.ts
Empty file.
14 changes: 11 additions & 3 deletions test/baseline.spec.ts
@@ -1,11 +1,16 @@
const puppeteer = require('puppeteer')
import * as fs from 'fs'
import * as path from 'path'
import * as assertions from './assertions'

import {build, open} from "./setup"

let browser = null

function toCamelCase(name: string) : string {
return name.replace(/-(.)/g, (_, char) => char.toUpperCase())
}

beforeAll(async () => {
browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox'],
Expand All @@ -18,14 +23,15 @@ describe('baseline', () => {
.filter((filename: string) => filename.endsWith('.vue'))
.map((filename: string) => filename.replace(/\.vue$/i, ''))
.forEach(fixture => {
test(fixture, () => testRunner(fixture, true))
test(fixture + ' (extract css)', () => testRunner(fixture, false))
const name = toCamelCase(fixture)
test(fixture, () => testRunner(fixture, true, assertions[name]))
test(fixture + ' (extract css)', () => testRunner(fixture, false, assertions[name]))
})
})

afterAll(async () => browser && (await browser.close()))

async function testRunner(fixture: string, extractCss: boolean): Promise<void> {
async function testRunner(fixture: string, extractCss: boolean, moreAssertions?: Function): Promise<void> {
const filename = path.join(__dirname, 'fixtures', fixture + '.vue')
const code = await build(filename, extractCss)
const page = await open(
Expand All @@ -43,5 +49,7 @@ async function testRunner(fixture: string, extractCss: boolean): Promise<void> {
)
).toEqual('rgb(255, 0, 0)')

moreAssertions && moreAssertions(page)

await page.close()
}
5 changes: 4 additions & 1 deletion test/setup/index.ts
Expand Up @@ -8,6 +8,7 @@ import {pluginCreateVueApp, plugins} from "./plugins"
import pluginVue from '../..'

const pluginCSS = require('rollup-plugin-css-only')
const assets = require('postcss-assets')

// -- rollup plugin inline file

Expand All @@ -18,7 +19,9 @@ export async function build(filename, css = false): Promise<string> {
if (cacheKey in cache) return cache[cacheKey]
let style: string | undefined
const input = filename + '__app.js'
const options = {defaultLang: {markdown: 'pluginMarkdown'}, css: css}
const options = {defaultLang: {markdown: 'pluginMarkdown'}, css: css, style: {
postcssPlugins: [assets({ basePath: '/' })]
}}
const bundle = await rollup({
input,
plugins: [
Expand Down
5 changes: 4 additions & 1 deletion test/setup/plugins.ts
@@ -1,18 +1,21 @@
const pluginBabel = require('rollup-plugin-babel')
const pluginNodeResolve = require('rollup-plugin-node-resolve')
const pluginCommonJS = require('rollup-plugin-commonjs')
const pluginImage = require('rollup-plugin-image')
const pluginImage = require('rollup-plugin-url')
const pluginMarkdown = require('rollup-plugin-md')
const pluginTypescript = require('rollup-plugin-typescript')
const pluginReplace = require('rollup-plugin-replace')
const path = require('path')

export const plugins = [
pluginImage(),
pluginMarkdown(),
pluginNodeResolve(),
pluginCommonJS(),
pluginReplace({ 'process.env.NODE_ENV': '"production"' }),
pluginTypescript({
tsconfig: false,
experimentalDecorators: true,
module: 'es2015'
}),
pluginBabel({
Expand Down