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

Commit 89839f2

Browse files
authored
fix: Transform require in render function compiled from <template> (#212)
1 parent 534c04b commit 89839f2

File tree

9 files changed

+205
-37
lines changed

9 files changed

+205
-37
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ output/
77
logs/
88
*.log
99
npm-debug.log*
10+
docs/changelog.md
1011

1112
# Runtime data
1213
pids

package.json

+13-4
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,20 @@
1919
},
2020
"standard-version": {
2121
"scripts": {
22-
"postchangelog": "yarn test && yarn docs && git add docs/"
22+
"postchangelog": "yarn test && yarn build:docs && git add docs/"
2323
}
2424
},
2525
"scripts": {
2626
"prepublishOnly": "yarn build",
2727
"prebuild": "yarn lint",
2828
"build": "tsc",
29+
"prebuild:docs": "cp CHANGELOG.md docs/changelog.md",
30+
"build:docs": "vuepress build docs/",
31+
"postbuild:docs": "rm docs/changelog.md",
2932
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 1",
30-
"docs": "typedoc typings src/index.ts && touch docs/.nojekyll",
33+
"predocs": "cp CHANGELOG.md docs/changelog.md",
34+
"docs": "vuepress dev docs/",
35+
"postdocs": "rm docs/CHANGELOG.md",
3136
"lint": "prettier --no-semi --single-quote --write **/*.js **/*.vue !test/target/** !dist/**",
3237
"release": "standard-version -a",
3338
"pretest": "yarn build",
@@ -43,7 +48,6 @@
4348
"@vue/component-compiler-utils": "^1.2.1",
4449
"debug": "^2.6.0",
4550
"hash-sum": "^1.0.2",
46-
"postcss": "^6.0.22",
4751
"querystring": "^0.2.0",
4852
"rollup-pluginutils": "^2.0.1"
4953
},
@@ -52,6 +56,7 @@
5256
"@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.46",
5357
"@babel/plugin-transform-runtime": "^7.0.0-beta.46",
5458
"@babel/preset-env": "^7.0.0-beta.46",
59+
"@types/debug": "^0.0.30",
5560
"@types/jest": "^22.2.3",
5661
"@types/node": "^10.0.4",
5762
"@types/puppeteer": "^1.3.1",
@@ -62,20 +67,24 @@
6267
"conventional-changelog": "^1.1.24",
6368
"jest": "^22.4.2",
6469
"node-sass": "^4.9.0",
70+
"postcss": "^6.0.22",
71+
"postcss-assets": "^5.0.0",
6572
"prettier": "^1.12.1",
6673
"pug": "^2.0.3",
6774
"puppeteer": "^1.4.0",
6875
"rollup": "^0.58.2",
6976
"rollup-plugin-babel": "^4.0.0-beta.4",
7077
"rollup-plugin-commonjs": "^9.1.3",
7178
"rollup-plugin-css-only": "^0.4.0",
72-
"rollup-plugin-image": "^1.0.2",
7379
"rollup-plugin-md": "^0.0.7",
7480
"rollup-plugin-node-resolve": "^3.3.0",
81+
"rollup-plugin-replace": "^2.0.0",
7582
"rollup-plugin-typescript": "^0.8.1",
83+
"rollup-plugin-url": "^1.4.0",
7684
"ts-jest": "^22.4.5",
7785
"typescript": "^2.8.3",
7886
"vue": "^2.5.16",
87+
"vue-class-component": "^6.2.0",
7988
"vue-template-compiler": "^2.5.16"
8089
},
8190
"peerDependencies": {

src/index.ts

+43-16
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {
33
createVuePartRequest,
44
parseVuePartRequest,
55
resolveVuePart,
6-
isVuePartRequest
6+
isVuePartRequest,
7+
transformRequireToImport
78
} from './utils'
89
import {
910
createDefaultCompiler,
@@ -13,26 +14,29 @@ import {
1314
TemplateOptions,
1415
StyleCompileResult
1516
} from '@vue/component-compiler'
16-
import {Plugin} from 'rollup'
17+
import { Plugin } from 'rollup'
1718
import * as path from 'path'
18-
import {parse, SFCDescriptor, SFCBlock} from '@vue/component-compiler-utils'
19+
import { parse, SFCDescriptor, SFCBlock } from '@vue/component-compiler-utils'
20+
import debug from 'debug'
1921

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

2226
export interface VuePluginOptions {
2327
/**
2428
* Include files or directories.
2529
* @default `'.vue'`
2630
*/
27-
include?: Array<string|RegExp> | string | RegExp
31+
include?: Array<string | RegExp> | string | RegExp
2832
/**
2933
* Exclude files or directories.
3034
* @default `undefined`
3135
*/
32-
exclude?: Array<string|RegExp> | string | RegExp
36+
exclude?: Array<string | RegExp> | string | RegExp
3337
/**
3438
* Default language for blocks.
35-
*
39+
*
3640
* @default `{}`
3741
* @example
3842
* ```js
@@ -41,7 +45,7 @@ export interface VuePluginOptions {
4145
*/
4246
defaultLang?: {
4347
[key: string]: string
44-
},
48+
}
4549
/**
4650
* Exclude customBlocks for final build.
4751
* @default `['*']`
@@ -99,7 +103,12 @@ export interface VuePluginOptions {
99103
*/
100104
export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
101105
const isVue = createVueFilter(opts.include, opts.exclude)
102-
const isProduction = process.env.NODE_ENV === 'production'
106+
const isProduction =
107+
process.env.NODE_ENV === 'production' || process.env.BUILD === 'production'
108+
109+
d('Version ' + version)
110+
d(`Build environment: ${isProduction ? 'production' : 'development'}`)
111+
d(`Build target: ${process.env.VUE_ENV || 'browser'}`)
103112

104113
createVuePartRequest.defaultLang = {
105114
...createVuePartRequest.defaultLang,
@@ -121,9 +130,23 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
121130
delete opts.include
122131
delete opts.exclude
123132

133+
opts.template = {
134+
transformAssetUrls: {
135+
video: ['src', 'poster'],
136+
source: 'src',
137+
img: 'src',
138+
image: 'xlink:href'
139+
},
140+
...opts.template
141+
} as any
142+
if (opts.template && typeof opts.template.isProduction === 'undefined') {
143+
opts.template.isProduction = isProduction
144+
}
124145
const compiler = createDefaultCompiler(opts)
125146
const descriptors = new Map<string, SFCDescriptor>()
126147

148+
if (opts.css === false) d('Running in CSS extract mode')
149+
127150
return {
128151
name: 'VuePlugin',
129152

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

156179
return 'code' in element
157-
? (element as any).code as string // .code is set when extract styles is used. { css: false }
180+
? ((element as any).code as string) // .code is set when extract styles is used. { css: false }
158181
: element.content
159182
},
160183

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

212+
input.template.code = transformRequireToImport(
213+
input.template.code
214+
)
215+
189216
if (input.template.errors && input.template.errors.length) {
190217
input.template.errors.map((error: Error) => this.error(error))
191218
}
@@ -197,7 +224,7 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
197224

198225
input.script = descriptor.script
199226
? {
200-
code: `
227+
code: `
201228
export * from '${createVuePartRequest(
202229
filename,
203230
descriptor.script.lang || 'js',
@@ -210,13 +237,13 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
210237
)}'
211238
export default script
212239
`
213-
}
214-
: {code: ''}
240+
}
241+
: { code: '' }
215242

216243
if (shouldExtractCss) {
217244
input.styles = input.styles
218245
.map((style: StyleCompileResult, index: number) => {
219-
(descriptor.styles[index] as any).code = style.code
246+
;(descriptor.styles[index] as any).code = style.code
220247

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

230257
if (style.module || descriptor.styles[index].scoped) {
231-
return {...style, code: ''}
258+
return { ...style, code: '' }
232259
}
233260
})
234261
.filter(Boolean)
@@ -243,8 +270,8 @@ export default function VuePlugin(opts: VuePluginOptions = {}): Plugin {
243270
`export * from '${createVuePartRequest(
244271
filename,
245272
block.attrs.lang ||
246-
createVuePartRequest.defaultLang[block.type] ||
247-
block.type,
273+
createVuePartRequest.defaultLang[block.type] ||
274+
block.type,
248275
'customBlocks',
249276
index
250277
)}'`

src/utils.ts

+16
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,19 @@ export function resolveVuePart(
123123

124124
return block
125125
}
126+
127+
export function transformRequireToImport(code: string): string {
128+
const imports: { [key: string]: string } = {}
129+
let strImports = ''
130+
131+
code = code.replace(/require\(("(?:[^"\\]|\\.)+"|'(?:[^'\\]|\\.)+')\)/g, (_, name): any => {
132+
if (!(name in imports)) {
133+
imports[name] = `__$_require_${name.replace(/[^a-z0-9]/g, '_').replace(/_{2,}/g, '_').replace(/^_|_$/g, '')}__`
134+
strImports += 'import ' + imports[name] + ' from ' + name + '\n'
135+
}
136+
137+
return imports[name]
138+
})
139+
140+
return strImports + code
141+
}

test/assertions.ts

Whitespace-only changes.

test/baseline.spec.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
const puppeteer = require('puppeteer')
22
import * as fs from 'fs'
33
import * as path from 'path'
4+
import * as assertions from './assertions'
45

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

78
let browser = null
89

10+
function toCamelCase(name: string) : string {
11+
return name.replace(/-(.)/g, (_, char) => char.toUpperCase())
12+
}
13+
914
beforeAll(async () => {
1015
browser = await puppeteer.launch({
1116
args: ['--no-sandbox', '--disable-setuid-sandbox'],
@@ -18,14 +23,15 @@ describe('baseline', () => {
1823
.filter((filename: string) => filename.endsWith('.vue'))
1924
.map((filename: string) => filename.replace(/\.vue$/i, ''))
2025
.forEach(fixture => {
21-
test(fixture, () => testRunner(fixture, true))
22-
test(fixture + ' (extract css)', () => testRunner(fixture, false))
26+
const name = toCamelCase(fixture)
27+
test(fixture, () => testRunner(fixture, true, assertions[name]))
28+
test(fixture + ' (extract css)', () => testRunner(fixture, false, assertions[name]))
2329
})
2430
})
2531

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

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

52+
moreAssertions && moreAssertions(page)
53+
4654
await page.close()
4755
}

test/setup/index.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {pluginCreateVueApp, plugins} from "./plugins"
88
import pluginVue from '../..'
99

1010
const pluginCSS = require('rollup-plugin-css-only')
11+
const assets = require('postcss-assets')
1112

1213
// -- rollup plugin inline file
1314

@@ -18,7 +19,9 @@ export async function build(filename, css = false): Promise<string> {
1819
if (cacheKey in cache) return cache[cacheKey]
1920
let style: string | undefined
2021
const input = filename + '__app.js'
21-
const options = {defaultLang: {markdown: 'pluginMarkdown'}, css: css}
22+
const options = {defaultLang: {markdown: 'pluginMarkdown'}, css: css, style: {
23+
postcssPlugins: [assets({ basePath: '/' })]
24+
}}
2225
const bundle = await rollup({
2326
input,
2427
plugins: [

test/setup/plugins.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
const pluginBabel = require('rollup-plugin-babel')
22
const pluginNodeResolve = require('rollup-plugin-node-resolve')
33
const pluginCommonJS = require('rollup-plugin-commonjs')
4-
const pluginImage = require('rollup-plugin-image')
4+
const pluginImage = require('rollup-plugin-url')
55
const pluginMarkdown = require('rollup-plugin-md')
66
const pluginTypescript = require('rollup-plugin-typescript')
7+
const pluginReplace = require('rollup-plugin-replace')
78
const path = require('path')
89

910
export const plugins = [
1011
pluginImage(),
1112
pluginMarkdown(),
1213
pluginNodeResolve(),
1314
pluginCommonJS(),
15+
pluginReplace({ 'process.env.NODE_ENV': '"production"' }),
1416
pluginTypescript({
1517
tsconfig: false,
18+
experimentalDecorators: true,
1619
module: 'es2015'
1720
}),
1821
pluginBabel({

0 commit comments

Comments
 (0)