From aa0c205540497a9db1fa7bf36e2c06328d81a7a3 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 15:25:31 -0400 Subject: [PATCH 01/52] drop promise polyfill --- lib/compiler.js | 1 - package.json | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index 09bb491..89a4976 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -1,4 +1,3 @@ -require('es6-promise').polyfill() var fs = require('fs') var path = require('path') var parse5 = require('parse5') diff --git a/package.json b/package.json index e11b99f..a143913 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "chalk": "^1.1.1", "cssnano": "^3.3.2", "de-indent": "^1.0.2", - "es6-promise": "^3.0.2", "hash-sum": "^1.0.2", "html-minifier": "^1.4.0", "lru-cache": "^2.7.0", From 63b3f7b0260cb0e9b70d5901d0780cee5271b17c Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 17:09:29 -0400 Subject: [PATCH 02/52] support Vue 2.0 --- index.js | 6 +- lib/compiler.js | 378 +++++++++------------------------------ lib/compilers/babel.js | 31 +++- lib/compilers/coffee.js | 6 +- lib/compilers/jade.js | 2 +- lib/compilers/less.js | 2 +- lib/compilers/options.js | 36 +--- lib/compilers/pug.js | 2 +- lib/compilers/sass.js | 6 +- lib/compilers/stylus.js | 2 +- lib/ensure-require.js | 13 +- lib/gen-id.js | 8 + lib/style-rewriter.js | 14 +- lib/template-rewriter.js | 49 ----- package.json | 18 +- 15 files changed, 157 insertions(+), 416 deletions(-) create mode 100644 lib/gen-id.js delete mode 100644 lib/template-rewriter.js diff --git a/index.js b/index.js index f15d38e..2e1b3a3 100644 --- a/index.js +++ b/index.js @@ -24,7 +24,11 @@ module.exports = function vueify (file, options) { compiler.compile(data, file, function(error, result) { compiler.removeListener('dependency', dependency) - if (error) stream.emit('error', error) + if (error) { + stream.emit('error', error) + // browserify doesn't log the stack by default... + console.error(error.stack.replace(/^.*?\n/, '')) + } stream.queue(result) stream.queue(null) }) diff --git a/lib/compiler.js b/lib/compiler.js index 89a4976..fab679b 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -1,35 +1,25 @@ var fs = require('fs') var path = require('path') -var parse5 = require('parse5') +var chalk = require('chalk') var hash = require('hash-sum') +var assign = require('object-assign') +var Emitter = require('events').EventEmitter +var vueCompiler = require('vue-template-compiler') + +var genId = require('./gen-id') var compilers = require('./compilers') var options = require('./compilers/options') var rewriteStyle = require('./style-rewriter') -var rewriteTemplate = require('./template-rewriter') -var validateTemplate = require('vue-template-validator') -var chalk = require('chalk') -var assign = require('object-assign') -var deindent = require('de-indent') -var Emitter = require('events').EventEmitter -// determine hot-reload-api location -var hotReloadAPIPath = 'vue-hot-reload-api' +var hasBabel = true try { - require(hotReloadAPIPath) + require('babel-core') } catch (e) { - // likely Npm 2.x - hotReloadAPIPath = 'vueify/node_modules/vue-hot-reload-api' + hasBabel = false } -var htmlMinifyOptions = { - collapseWhitespace: true, - removeComments: true, - collapseBooleanAttributes: true, - removeAttributeQuotes: true, - useShortDoctype: true, - removeEmptyAttributes: true, - removeOptionalTags: true -} +// determine hot-reload-api location +var hotReloadAPIPath = normalizeDep('vue-hot-reload-api') // expose compiler var compiler = module.exports = new Emitter() @@ -49,11 +39,7 @@ compiler.loadConfig = function () { compiler.applyConfig = function (config) { // copy user options to default options Object.keys(config).forEach(function (key) { - if (key === 'htmlMinifier') { - if (process.env.NODE_ENV === 'production') { - htmlMinifyOptions = assign(htmlMinifyOptions, config[key]) - } - } else if (key !== 'customCompilers') { + if (key !== 'customCompilers') { options[key] = config[key] } else { // register compilers @@ -64,59 +50,36 @@ compiler.applyConfig = function (config) { }) } -/** - * Compile a .vue file. - * - * @param {String} content - * @param {String} [filePath] - * @param {Function} cb - */ compiler.compile = function (content, filePath, cb) { - // path is optional - if (typeof filePath === 'function') { - cb = filePath - filePath = process.cwd() - } - // generate css scope id - var id = '_v-' + hash(filePath || content) - - // parse the file into an HTML tree - var fragment = parse5.parseFragment(content, { locationInfo: true }) - - // check node numbers - if (!validateNodeCount(fragment)) { - return cb(new Error( - 'Only one script tag and one template tag allowed per *.vue file.' - )) - } + var id = 'data-v-' + genId(filePath) + // parse the component into parts + var parts = vueCompiler.parseComponent(content) // check for scoped style nodes - var hasScopedStyle = fragment.childNodes.some(function (node) { - return node.nodeName === 'style' && isScoped(node) + var hasScopedStyle = parts.styles.some(function (style) { + return style.scoped }) - // Walk through the top level nodes and check for their - // types & languages. If there are pre-processing needed, - // push it into a jobs list. - Promise.all(fragment.childNodes.map(function (node) { - switch (node.nodeName) { - case 'template': - return processTemplate(node, filePath, id, hasScopedStyle, content) - case 'style': - return processStyle(node, filePath, id) - case 'script': - return processScript(node, filePath, content) - } - }) - .filter(function (p) { return p })) - .then(mergeParts, cb) + var resolvedParts = { + template: null, + script: null, + styles: [] + } + + Promise.all([ + processTemplate(parts.template, filePath, resolvedParts), + processScript(parts.script, filePath, resolvedParts) + ].concat(parts.styles.map(function (style) { + return processStyle(style, filePath, id, resolvedParts) + }))) + .then(mergeParts) .catch(cb) - function mergeParts (parts) { + function mergeParts () { var output = '' // styles - var style = extract(parts, 'style') + var style = resolvedParts.styles.join('\n') if (style) { style = JSON.stringify(style) output += @@ -124,7 +87,7 @@ compiler.compile = function (content, filePath, cb) { 'var __vueify_style__ = __vueify_insert__.insert(' + style + ')\n' } // script - var script = extract(parts, 'script') + var script = resolvedParts.script if (script) { output += script + '\n' + @@ -132,21 +95,23 @@ compiler.compile = function (content, filePath, cb) { 'if (module.exports.__esModule) module.exports = module.exports.default\n' } // template - var template = extract(parts, 'template') + var template = resolvedParts.template if (template) { output += - ';(typeof module.exports === "function"' + + 'var __vue__options__ = (typeof module.exports === "function"' + '? module.exports.options' + - ': module.exports).template = ' + JSON.stringify(template) + '\n' + ': module.exports)\n' + + '__vue__options__.render = ' + template.render + '\n' + + '__vue__options__.staticRenderFns = ' + template.staticRenderFns + '\n' } // hot reload if (process.env.NODE_ENV !== 'production' && !process.env.VUEIFY_TEST) { output += 'if (module.hot) {(function () {' + - ' module.hot.accept()\n' + ' var hotAPI = require("' + hotReloadAPIPath + '")\n' + ' hotAPI.install(require("vue"), true)\n' + ' if (!hotAPI.compatible) return\n' + + ' module.hot.accept()\n' + // remove style tag on dispose (style ? ' module.hot.dispose(function () {\n' + @@ -160,214 +125,64 @@ compiler.compile = function (content, filePath, cb) { ' hotAPI.createRecord("' + id + '", module.exports)\n' + ' } else {\n' + // update - ' hotAPI.update("' + id + '", module.exports, (typeof module.exports === "function" ? module.exports.options : module.exports).template)\n' + + ' hotAPI.reload("' + id + '", module.exports)\n' + ' }\n' + '})()}' } + console.log(output) cb(null, output) } } -/** - * Ensure there's only one template node. - * - * @param {Fragment} fragment - * @return {Boolean} - */ - -function validateNodeCount (fragment) { - var count = 0 - fragment.childNodes.forEach(function (node) { - if (node.nodeName === 'template') { - count++ - } - }) - return count <= 1 -} - -/** - * Check if a style node is scoped. - * - * @param {Node} node - * @return {Boolean} - */ - -function isScoped (node) { - return node.attrs && node.attrs.some(function (attr) { - return attr.name === 'scoped' - }) -} - -/** - * Process a template node - * - * @param {Node} node - * @param {String} filePath - * @param {String} id - * @param {Boolean} hasScopedStyle - * @param {String} fullSource - * @return {Promise} - */ - -function processTemplate (node, filePath, id, hasScopedStyle, fullSource) { - var lang = checkLang(node) - var template = checkSrc(node, filePath) || ( - lang - ? getRawTemplate(node, fullSource) // custom template, extract as raw string - : parse5.serialize(node.content) // normal HTML, use serialization - ) - template = deindent(template) - if (!lang) { - var warnings = validateTemplate(node.content, fullSource) - if (warnings) { - var relativePath = path.relative(process.cwd(), filePath) - warnings.forEach(function (msg) { - console.warn(chalk.red('\n Error in ' + relativePath + ':\n') + msg) - }) - } - } - return compileAsPromise('template', template, lang, filePath) - .then(function (res) { - if (hasScopedStyle) { - return rewriteTemplate(id, res.source) - } else { - return res - } - }) +function processTemplate (part, filePath, parts) { + var template = getContent(part, filePath) + return compileAsPromise('template', template, part.lang, filePath) .then(function (res) { - if (process.env.NODE_ENV === 'production') { - res.source = require('html-minifier').minify(res.source, htmlMinifyOptions) + var compiled = vueCompiler.compile(res) + parts.template = { + render: toFunction(compiled.render), + staticRenderFns: '[' + compiled.staticRenderFns.map(toFunction).join(',') + ']' } - return res }) } -/** - * Extract the raw content of a template node. - * This is more reliable because if the user uses a template language - * that would confuse parse5 (e.g. ejs), the serialization result - * would be different from original. - * - * @param {Node} node - * @param {String} source - */ - -function getRawTemplate (node, source) { - var content = node.content - var l = content.childNodes.length - if (!l) return '' - var start = content.childNodes[0].__location.startOffset - var end = content.childNodes[l - 1].__location.endOffset - return source.slice(start, end) -} - -/** - * Process a style node - * - * @param {Node} node - * @param {String} id - * @param {String} filePath - * @return {Promise} - */ - -function processStyle (node, filePath, id) { - var style = checkSrc(node, filePath) || parse5.serialize(node) - var lang = checkLang(node) - style = deindent(style) - return compileAsPromise('style', style, lang, filePath) +function processScript (part, filePath, parts) { + var lang = part.lang || (hasBabel ? 'babel' : null) + var script = getContent(part, filePath) + return compileAsPromise('script', script, lang, filePath) .then(function (res) { - return rewriteStyle(id, res.source, isScoped(node)) + parts.script = res }) } -/** - * Process a script node - * - * @param {Node} node - * @param {String} filePath - * @param {String} content - * @return {Promise} - */ - -function processScript (node, filePath, content) { - var lang = checkLang(node) || 'babel' - var script = checkSrc(node, filePath) - if (!script) { - script = parse5.serialize(node) - // pad the script to ensure correct line number for syntax errors - var location = content.indexOf(script) - var before = padContent(content.slice(0, location)) - script = before + script - } - script = deindent(script) - return compileAsPromise('script', script, lang, filePath) +function processStyle (part, filePath, id, parts) { + var style = getContent(part) + return compileAsPromise('style', style, part.lang, filePath) + .then(function (res) { + parts.styles.push(rewriteStyle(id, res, part.scoped)) + }) } -/** - * Check the lang attribute of a parse5 node. - * - * @param {Node} node - * @return {String|undefined} - */ - -function checkLang (node) { - if (node.attrs) { - var i = node.attrs.length - while (i--) { - var attr = node.attrs[i] - if (attr.name === 'lang') { - return attr.value - } - } - } +function getContent (part, filePath) { + return part.src + ? loadSrc(part.src, filePath) + : part.content } -/** - * Check src import for a node, relative to the filePath if - * available. Using readFileSync for now since this is a - * rare use case. - * - * @param {Node} node - * @param {String} filePath - * @return {String} - */ - -function checkSrc (node, filePath) { +function loadSrc (src, filePath) { var dir = path.dirname(filePath) - if (node.attrs) { - var i = node.attrs.length - while (i--) { - var attr = node.attrs[i] - if (attr.name === 'src') { - var src = attr.value - if (src) { - filePath = path.resolve(dir, src) - compiler.emit('dependency', filePath) - try { - return fs.readFileSync(filePath, 'utf-8') - } catch (e) { - console.warn( - 'Failed to load src: "' + src + - '" from file: "' + filePath + '"' - ) - } - } - } - } + var filePath = path.resolve(dir, src) + compiler.emit('dependency', filePath) + try { + return fs.readFileSync(filePath, 'utf-8') + } catch (e) { + console.warn( + 'Failed to load src: "' + src + + '" from file: "' + filePath + '"' + ) } } -/** - * Compile a piece of source code with an async compiler and - * return a Promise. - * - * @param {String} type - * @param {String} source - * @param {String} lang - * @param {String} filePath - * @return {Promise} - */ - function compileAsPromise (type, source, lang, filePath) { var compile = compilers[lang] if (compile) { @@ -382,45 +197,26 @@ function compileAsPromise (type, source, lang, filePath) { } return reject(err) } - resolve({ - source: res, - type: type - }) + resolve(res) }, compiler, filePath) }) } else { - return Promise.resolve({ - source: source, - type: type - }) + return Promise.resolve(source) } } -/** - * Extract parts from resolved array. - * - * @param {Array} parts - * @param {String} type - */ - -function extract (parts, type) { - return parts - .filter(function (part) { - return part.type === type - }) - .map(function (part) { - return part.source - }) - .join('\n') +function toFunction (code) { + return 'function(){' + code + '}' } -/** - * Pad content into empty lines. - */ - -function padContent (content, lang) { - return content - .split(/\r?\n/g) - .map(function () { return '' }) - .join('\n') +function normalizeDep (dep) { + if (process.env.VUEIFY_TEST) { + return dep + } else if (fs.existsSync(path.resolve(__dirname, '../node_modules', dep))) { + // npm 2 or npm linked + return 'vueify/node_modules/' + dep + } else { + // npm 3 + return dep + } } diff --git a/lib/compilers/babel.js b/lib/compilers/babel.js index 538decc..001beff 100644 --- a/lib/compilers/babel.js +++ b/lib/compilers/babel.js @@ -1,11 +1,36 @@ +var fs = require('fs') +var path = require('path') var options = require('./options') -var ensureRequire = require('../ensure-require.js') +var ensureRequire = require('../ensure-require') + +var defaultBabelOptions = { + presets: ['es2015'], + plugins: ['transform-runtime'] +} + +var babelRcPath = path.resolve(process.cwd(), '.babelrc') +var babelOptions = fs.existsSync(babelRcPath) + ? getBabelRc() || defaultBabelOptions + : defaultBabelOptions + +function getBabelRc () { + var rc + try { + rc = JSON.parse(fs.readFileSync(babelRcPath, 'utf-8')) + } catch (e) { + throw new Error('[vueify] Your .babelrc seems to be incorrectly formatted.') + } + return rc +} + +if (babelOptions === defaultBabelOptions) { + ensureRequire('babel', ['babel-preset-es2015', 'babel-runtime', 'babel-plugin-transform-runtime']) +} module.exports = function (raw, cb) { - ensureRequire('babel',['babel-core','babel-preset-es2015','babel-plugin-transform-runtime',['babel-runtime/core-js.js','babel-runtime']]) try { var babel = require('babel-core') - var res = babel.transform(raw, options.babel || {}) + var res = babel.transform(raw, options.babel || babelOptions) } catch (err) { return cb(err) } diff --git a/lib/compilers/coffee.js b/lib/compilers/coffee.js index 4f5dffa..9f277a8 100644 --- a/lib/compilers/coffee.js +++ b/lib/compilers/coffee.js @@ -2,10 +2,12 @@ var options = require('./options') var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb) { - ensureRequire('coffee',['coffee-script']) + ensureRequire('coffee', ['coffee-script']) var coffee = require('coffee-script') try { - var js = coffee.compile(raw, options.coffee || {}) + var js = coffee.compile(raw, options.coffee || { + bare: true + }) } catch (err) { return cb(err) } diff --git a/lib/compilers/jade.js b/lib/compilers/jade.js index 45980df..021e81f 100644 --- a/lib/compilers/jade.js +++ b/lib/compilers/jade.js @@ -2,7 +2,7 @@ var options = require('./options') var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb) { - ensureRequire('jade','jade') + ensureRequire('jade', 'jade') var jade = require('jade') try { var html = jade.compile(raw, options.jade || {})() diff --git a/lib/compilers/less.js b/lib/compilers/less.js index 1b571c8..b9d5335 100644 --- a/lib/compilers/less.js +++ b/lib/compilers/less.js @@ -4,7 +4,7 @@ var path = require('path') var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb, compiler, filePath) { - ensureRequire('less','less') + ensureRequire('less', 'less') var less = require('less') var opts = assign({ diff --git a/lib/compilers/options.js b/lib/compilers/options.js index 2a5cd5b..4ba52ba 100644 --- a/lib/compilers/options.js +++ b/lib/compilers/options.js @@ -1,35 +1 @@ -var fs = require('fs') -var path = require('path') - -var defaultBabelOptions = { - presets: ['es2015'], - plugins: ['transform-runtime'] -} - -var babelRcPath = path.resolve(process.cwd(), '.babelrc') -var babelOptions = fs.existsSync(babelRcPath) - ? getBabelRc() || defaultBabelOptions - : defaultBabelOptions - -function getBabelRc () { - var rc - try { - rc = JSON.parse(fs.readFileSync(babelRcPath, 'utf-8')) - } catch (e) { - throw new Error('[vueify] Your .babelrc seems to be incorrectly formatted.') - } - return rc -} - -module.exports = { - autoprefixer: { - remove: false - }, - babel: babelOptions, - coffee: { - bare: true - }, - sass: { - sourceComments: true - } -} +module.exports = {} diff --git a/lib/compilers/pug.js b/lib/compilers/pug.js index 4fd384f..7ed9d20 100644 --- a/lib/compilers/pug.js +++ b/lib/compilers/pug.js @@ -2,7 +2,7 @@ var options = require('./options') var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb) { - ensureRequire('pug','pug') + ensureRequire('pug', 'pug') var pug = require('pug') try { var html = pug.compile(raw, options.pug || {})() diff --git a/lib/compilers/sass.js b/lib/compilers/sass.js index 20d696f..4a825c4 100644 --- a/lib/compilers/sass.js +++ b/lib/compilers/sass.js @@ -4,7 +4,7 @@ var path = require('path') var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb, compiler, filePath) { - ensureRequire('sass','node-sass') + ensureRequire('sass', 'node-sass') var sass = require('node-sass') var sassOptions = assign({ @@ -19,7 +19,9 @@ module.exports = function (raw, cb, compiler, filePath) { error: function (err) { cb(err) } - }, options.sass) + }, options.sass || { + sourceComments: true + }) var dir = path.dirname(filePath) var paths = [dir, process.cwd()] diff --git a/lib/compilers/stylus.js b/lib/compilers/stylus.js index 0f05720..c63d174 100644 --- a/lib/compilers/stylus.js +++ b/lib/compilers/stylus.js @@ -4,7 +4,7 @@ var path = require('path') var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb, compiler, filePath) { - ensureRequire('stylus','stylus') + ensureRequire('stylus', 'stylus') var stylus = require('stylus') var opts = assign({ diff --git a/lib/ensure-require.js b/lib/ensure-require.js index ad4800c..0bd9fb4 100644 --- a/lib/ensure-require.js +++ b/lib/ensure-require.js @@ -1,5 +1,6 @@ -module.exports = function(name,deps) { - var i,len,missing=[]; +module.exports = function (name, deps) { + var i, len + var missing = [] if (typeof deps === "string") { deps = [deps] } @@ -18,15 +19,15 @@ module.exports = function(name,deps) { } } if (missing.length > 0) { - var message = 'You are trying to use "'+name+'". ' - var npmInstall = 'npm install --save-dev '+missing.join(" ") + var message = 'You are trying to use "' + name + '". ' + var npmInstall = 'npm install --save-dev ' + missing.join(" ") if (missing.length > 1) { var last = missing.pop() - message += missing.join(', ') + ' and ' +last + ' are ' + message += missing.join(', ') + ' and ' + last + ' are ' } else { message += missing[0] + ' is ' } - message += 'missing.\n\nTo install run:\n'+npmInstall + message += 'missing.\n\nTo install run:\n' + npmInstall throw new Error(message) } } diff --git a/lib/gen-id.js b/lib/gen-id.js new file mode 100644 index 0000000..25281ae --- /dev/null +++ b/lib/gen-id.js @@ -0,0 +1,8 @@ +// utility for generating a uid for each component file +// used in scoped CSS rewriting +var fileUid = 1 +var fileRegistry = Object.create(null) + +module.exports = function genId (file) { + return fileRegistry[file] || (fileRegistry[file] = fileUid++) +} diff --git a/lib/style-rewriter.js b/lib/style-rewriter.js index a212d0a..17a0250 100644 --- a/lib/style-rewriter.js +++ b/lib/style-rewriter.js @@ -52,15 +52,9 @@ module.exports = function (id, css, scoped) { if (scoped) { plugins.push(addId) } - // autoprefixing - if (options.autoprefixer !== false) { - var autoprefixer = require('autoprefixer')(options.autoprefixer) - plugins.push(autoprefixer) - } // minification if (process.env.NODE_ENV === 'production') { plugins.push(require('cssnano')(assign({ - autoprefixer: false, safe: true }, options.cssnano))) } @@ -68,12 +62,8 @@ module.exports = function (id, css, scoped) { return postcss(plugins) .process(css) .then(function (res) { - var val = { - source: res.css, - type: 'style' - } - cache.set(key, val) - return val + cache.set(key, res.css) + return res.css }) } } diff --git a/lib/template-rewriter.js b/lib/template-rewriter.js deleted file mode 100644 index 8acf1f0..0000000 --- a/lib/template-rewriter.js +++ /dev/null @@ -1,49 +0,0 @@ -var parse5 = require('parse5') -var cache = require('lru-cache')(100) - -/** - * Add attribute to template - * - * @param {String} id - * @param {String} html - * @return {String} - */ - -module.exports = function (id, html) { - var key = id + '!!' + html - var val = cache.get(key) - if (val) { - return Promise.resolve(val) - } - var tree = parse5.parseFragment(html) - walk(tree, function (node) { - if (node.attrs) { - node.attrs.push({ - name: id, - value: '' - }) - } - }) - val = { - source: parse5.serialize(tree), - type: 'template' - } - cache.set(key, val) - return Promise.resolve(val) -} - -function walk (tree, fn) { - if (tree.childNodes) { - tree.childNodes.forEach(function (node) { - var isTemplate = node.tagName === 'template' - if (!isTemplate) { - fn(node) - } - if (isTemplate && node.content) { - walk(node.content, fn) - } else { - walk(node, fn) - } - }) - } -} diff --git a/package.json b/package.json index a143913..c4fd6a0 100644 --- a/package.json +++ b/package.json @@ -21,25 +21,21 @@ }, "homepage": "https://github.com/vuejs/vueify", "dependencies": { - "autoprefixer": "^6.0.3", "chalk": "^1.1.1", "cssnano": "^3.3.2", - "de-indent": "^1.0.2", "hash-sum": "^1.0.2", - "html-minifier": "^1.4.0", - "lru-cache": "^2.7.0", + "lru-cache": "^4.0.0", "object-assign": "^4.0.1", - "parse5": "^2.1.0", "postcss": "^5.0.10", - "postcss-selector-parser": "^1.3.0", + "postcss-selector-parser": "^2.0.0", "through": "^2.3.6", - "vue-hot-reload-api": "^1.3.2", - "vue-template-validator": "^1.0.1" + "vue-hot-reload-api": "^2.0.1", + "vue-template-compiler": "^2.0.0-alpha.3" }, "devDependencies": { - "babel-core": "^6.8.0", - "babel-plugin-transform-runtime": "^6.6.1", - "babel-preset-es2015": "^6.6.0", + "babel-core": "^6.0.0", + "babel-plugin-transform-runtime": "^6.0.0", + "babel-preset-es2015": "^6.0.0", "babel-runtime": "^6.0.0", "coffee-script": "^1.10.0", "jade": "^1.11.0", From 615dded3e66388a5fda3c383c7498bc78cdbf278 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 17:15:55 -0400 Subject: [PATCH 03/52] fix scoped CSS --- lib/compiler.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index fab679b..9ef9072 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -94,16 +94,21 @@ compiler.compile = function (content, filePath, cb) { // babel 6 compat 'if (module.exports.__esModule) module.exports = module.exports.default\n' } + // in case the user exports with Vue.extend + output += 'var __vue__options__ = (typeof module.exports === "function"' + + '? module.exports.options' + + ': module.exports)\n' // template var template = resolvedParts.template if (template) { output += - 'var __vue__options__ = (typeof module.exports === "function"' + - '? module.exports.options' + - ': module.exports)\n' + '__vue__options__.render = ' + template.render + '\n' + '__vue__options__.staticRenderFns = ' + template.staticRenderFns + '\n' } + // scoped CSS id + if (hasScopedStyle) { + output += '__vue__options__._scopeId = "' + id + '"\n' + } // hot reload if (process.env.NODE_ENV !== 'production' && !process.env.VUEIFY_TEST) { output += @@ -122,14 +127,13 @@ compiler.compile = function (content, filePath, cb) { ) + ' if (!module.hot.data) {\n' + // initial insert - ' hotAPI.createRecord("' + id + '", module.exports)\n' + + ' hotAPI.createRecord("' + id + '", __vue__options__)\n' + ' } else {\n' + // update - ' hotAPI.reload("' + id + '", module.exports)\n' + + ' hotAPI.reload("' + id + '", __vue__options__)\n' + ' }\n' + '})()}' } - console.log(output) cb(null, output) } } @@ -159,7 +163,9 @@ function processStyle (part, filePath, id, parts) { var style = getContent(part) return compileAsPromise('style', style, part.lang, filePath) .then(function (res) { - parts.styles.push(rewriteStyle(id, res, part.scoped)) + return rewriteStyle(id, res, part.scoped).then(function (res) { + parts.styles.push(res) + }) }) } From 15c99ed54e10294d3f1c24f40a7d2388b135e58e Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 17:20:33 -0400 Subject: [PATCH 04/52] better babel warning --- lib/compilers/babel.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/compilers/babel.js b/lib/compilers/babel.js index 001beff..ebbb7bf 100644 --- a/lib/compilers/babel.js +++ b/lib/compilers/babel.js @@ -24,7 +24,16 @@ function getBabelRc () { } if (babelOptions === defaultBabelOptions) { - ensureRequire('babel', ['babel-preset-es2015', 'babel-runtime', 'babel-plugin-transform-runtime']) + try { + ensureRequire('babel', ['babel-preset-es2015', 'babel-runtime', 'babel-plugin-transform-runtime']) + } catch (e) { + console.error(e.message) + console.error( + '\n^^^ You are seeing this because you are using Vueify\'s default babel ' + + 'configuration. You can override this with .babelrc or the babel option ' + + 'in vue.config.js.' + ) + } } module.exports = function (raw, cb) { From 3914e57b95dcd5bdbd06ab0a188f633328d83a8d Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 17:35:54 -0400 Subject: [PATCH 05/52] fix optional parts / strict mode --- lib/compiler.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/compiler.js b/lib/compiler.js index 9ef9072..6cddcd1 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -90,7 +90,7 @@ compiler.compile = function (content, filePath, cb) { var script = resolvedParts.script if (script) { output += - script + '\n' + + ';(function(){' + script + '})()\n' + // babel 6 compat 'if (module.exports.__esModule) module.exports = module.exports.default\n' } @@ -139,6 +139,7 @@ compiler.compile = function (content, filePath, cb) { } function processTemplate (part, filePath, parts) { + if (!part) return Promise.resolve() var template = getContent(part, filePath) return compileAsPromise('template', template, part.lang, filePath) .then(function (res) { @@ -151,6 +152,7 @@ function processTemplate (part, filePath, parts) { } function processScript (part, filePath, parts) { + if (!part) return Promise.resolve() var lang = part.lang || (hasBabel ? 'babel' : null) var script = getContent(part, filePath) return compileAsPromise('script', script, lang, filePath) From e5cb32a015f506ea5df0e07bcb64ae2d51d0801c Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 19:06:35 -0400 Subject: [PATCH 06/52] new test setup --- .gitignore | 3 +- circle.yml | 3 + lib/compiler.js | 30 ++++----- lib/ensure-require.js | 4 ++ lib/normalize.js | 23 +++++++ package.json | 7 ++- test/fixtures/autoprefix.vue | 5 -- test/fixtures/basic.vue | 28 ++++----- test/test.js | 117 ++++++++++++++--------------------- 9 files changed, 107 insertions(+), 113 deletions(-) create mode 100644 circle.yml create mode 100644 lib/normalize.js delete mode 100644 test/fixtures/autoprefix.vue diff --git a/.gitignore b/.gitignore index 91dfed8..6218a0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store -node_modules \ No newline at end of file +node_modules +test/temp diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000..b00026e --- /dev/null +++ b/circle.yml @@ -0,0 +1,3 @@ +machine: + node: + version: 6 diff --git a/lib/compiler.js b/lib/compiler.js index 6cddcd1..b5c5ccd 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -7,6 +7,7 @@ var Emitter = require('events').EventEmitter var vueCompiler = require('vue-template-compiler') var genId = require('./gen-id') +var normalize = require('./normalize') var compilers = require('./compilers') var options = require('./compilers/options') var rewriteStyle = require('./style-rewriter') @@ -18,8 +19,9 @@ try { hasBabel = false } -// determine hot-reload-api location -var hotReloadAPIPath = normalizeDep('vue-hot-reload-api') +// determine dynamic script paths +var hotReloadAPIPath = normalize.dep('vue-hot-reload-api') +var insertCSSPath = normalize.lib('insert-css') // expose compiler var compiler = module.exports = new Emitter() @@ -83,7 +85,7 @@ compiler.compile = function (content, filePath, cb) { if (style) { style = JSON.stringify(style) output += - 'var __vueify_insert__ = require("vueify/lib/insert-css")\n' + + 'var __vueify_insert__ = require("' + insertCSSPath + '")\n' + 'var __vueify_style__ = __vueify_insert__.insert(' + style + ')\n' } // script @@ -144,9 +146,13 @@ function processTemplate (part, filePath, parts) { return compileAsPromise('template', template, part.lang, filePath) .then(function (res) { var compiled = vueCompiler.compile(res) - parts.template = { - render: toFunction(compiled.render), - staticRenderFns: '[' + compiled.staticRenderFns.map(toFunction).join(',') + ']' + if (compiled.errors.length) { + throw new Error(compiled.errors.join('\n\n')) + } else { + parts.template = { + render: toFunction(compiled.render), + staticRenderFns: '[' + compiled.staticRenderFns.map(toFunction).join(',') + ']' + } } }) } @@ -216,15 +222,3 @@ function compileAsPromise (type, source, lang, filePath) { function toFunction (code) { return 'function(){' + code + '}' } - -function normalizeDep (dep) { - if (process.env.VUEIFY_TEST) { - return dep - } else if (fs.existsSync(path.resolve(__dirname, '../node_modules', dep))) { - // npm 2 or npm linked - return 'vueify/node_modules/' + dep - } else { - // npm 3 - return dep - } -} diff --git a/lib/ensure-require.js b/lib/ensure-require.js index 0bd9fb4..8c041b0 100644 --- a/lib/ensure-require.js +++ b/lib/ensure-require.js @@ -13,6 +13,10 @@ module.exports = function (name, deps) { req = req[0] } try { + // hack for babel-runtime because it does not expose "main" field + if (req === 'babel-runtime') { + req = 'babel-runtime/core-js' + } require.resolve(req) } catch (e) { missing.push(mis) diff --git a/lib/normalize.js b/lib/normalize.js new file mode 100644 index 0000000..54b8dc4 --- /dev/null +++ b/lib/normalize.js @@ -0,0 +1,23 @@ +var IS_TEST = !!process.env.VUEIFY_TEST +var fs = require('fs') +var path = require('path') + +exports.lib = function (file) { + if (IS_TEST) { + return path.resolve(__dirname, file) + } else { + return 'vueify/lib/' + file + } +} + +exports.dep = function (dep) { + if (IS_TEST) { + return dep + } else if (fs.existsSync(path.resolve(__dirname, '../node_modules', dep))) { + // npm 2 or npm linked + return 'vueify/node_modules/' + dep + } else { + // npm 3 + return dep + } +} diff --git a/package.json b/package.json index c4fd6a0..8d81c92 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "url": "https://github.com/vuejs/vueify/issues" }, "scripts": { - "test": "NODE_ENV=production mocha test/test.js --slow=5000 --timeout=10000" + "test": "mocha test/test.js --slow=5000 --timeout=10000" }, "homepage": "https://github.com/vuejs/vueify", "dependencies": { @@ -37,13 +37,16 @@ "babel-plugin-transform-runtime": "^6.0.0", "babel-preset-es2015": "^6.0.0", "babel-runtime": "^6.0.0", + "browserify": "^13.0.1", + "chai": "^3.5.0", "coffee-script": "^1.10.0", "jade": "^1.11.0", + "jsdom": "^9.2.1", "less": "^2.5.1", "mocha": "^2.3.3", "node-sass": "^3.3.3", "pug": "^2.0.0-alpha6", - "rewire": "^2.5.1", + "rimraf": "^2.5.2", "stylus": "^0.52.4" } } diff --git a/test/fixtures/autoprefix.vue b/test/fixtures/autoprefix.vue deleted file mode 100644 index a5308b2..0000000 --- a/test/fixtures/autoprefix.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/test/fixtures/basic.vue b/test/fixtures/basic.vue index 3996ac9..5dce8c7 100644 --- a/test/fixtures/basic.vue +++ b/test/fixtures/basic.vue @@ -1,25 +1,19 @@ - - + + diff --git a/test/test.js b/test/test.js index 202799a..fc23e02 100644 --- a/test/test.js +++ b/test/test.js @@ -1,75 +1,52 @@ -var fs = require('fs') -var path = require('path') -var compiler = require('../lib/compiler') -var assert = require('assert') -var hash = require('hash-sum') - -// test custom transform -compiler.applyConfig({ - customCompilers: { - test: function (content, cb) { - content = content.replace('not ', '') - cb(null, content) - } - } -}) - -function read (file) { - return fs.readFileSync(path.resolve(__dirname, file), 'utf-8') -} - -function test (name) { - it(name, function (done) { - var filePath = 'fixtures/' + name + '.vue' - var fileContent = read(filePath) - var expected = read('expects/' + name + '.js') - .replace(/\{\{id\}\}/g, '_v-' + hash(require.resolve('./' + filePath))) - - // test registering dependency - var deps = [] - function addDep (file) { - deps.push(file) - } - compiler.on('dependency', addDep) - - process.env.VUEIFY_TEST = true - process.env.NODE_ENV = name === 'non-minified' - ? 'development' - : 'production' - - compiler.compile( - fileContent, - path.resolve(__dirname, filePath), - function (err, result) { - // the cb is handled by a Promise, so the assertion - // errors gets swallowed and the test never fails. - // do it in a separate tick. - setTimeout(function () { - if (err) throw err - assert.equal(result, expected, 'should compile correctly') - - // check src - if (name === 'src') { - assert.equal(deps[0], __dirname + '/fixtures/test.html') - assert.equal(deps[1], __dirname + '/fixtures/test.styl') - assert.equal(deps[2], __dirname + '/fixtures/src/test.js') - } - - if (name === 'less' || name === 'sass' || name === 'styl') { - assert.equal(deps[0], __dirname + '/fixtures/imports/import.' + name) +process.env.VUEIFY_TEST = true + +const fs = require('fs') +const path = require('path') +const expect = require('chai').expect +const hash = require('hash-sum') +const rimraf = require('rimraf') +const mkdirp = require('mkdirp') +const browserify = require('browserify') +const vueify = require('../index') +const jsdom = require('jsdom') +const vueCompiler = require('vue-template-compiler') + +const tempDir = path.resolve(__dirname, './temp') +const mockEntry = path.resolve(tempDir, 'entry.js') +rimraf.sync(tempDir) +mkdirp.sync(tempDir) + +function test (file, assert) { + it(file, done => { + fs.writeFileSync(mockEntry, 'window.vueModule = require("../fixtures/' + file + '.vue")') + browserify(mockEntry) + .transform(vueify) + .bundle((err, buf) => { + if (err) return done(err) + jsdom.env({ + html: '', + src: [buf.toString()], + done: (err, window) => { + if (err) return done(err) + assert(window) + done() } - - compiler.removeListener('dependency', addDep) - done() - }, 0) - } - ) + }) + }) }) } -describe('Vueify compiler', function () { - fs.readdirSync(path.resolve(__dirname, 'expects')) - .forEach(function (file) { - test(path.basename(file, '.js')) - }) +function assertRenderFn (options, template) { + const compiled = vueCompiler.compile(template) + expect(options.render.toString()).to.equal('function (){' + compiled.render + '}') +} + +describe('vueify', () => { + test('basic', window => { + const module = window.vueModule + assertRenderFn(module, '

{{msg}}

') + expect(module.data().msg).to.contain('Hello from Component A!') + const style = window.document.querySelector('style').textContent + expect(style).to.contain('comp-a h2 {\n color: #f00;\n}') + }) }) From 0ec591dee7c884f22abd5c8cb267ec4cd941e072 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 19:43:07 -0400 Subject: [PATCH 07/52] refactor tests --- lib/compiler.js | 2 +- test/expects/autoprefix.js | 2 - test/expects/basic.js | 41 --------------- test/expects/custom.js | 4 -- test/expects/empty.js | 0 test/expects/jade.js | 1 - test/expects/less.js | 2 - test/expects/multiple-scripts.js | 12 ----- test/expects/multiple-styles.js | 2 - test/expects/multiple.js | 18 ------- test/expects/non-minified.js | 3 -- test/expects/pug.js | 1 - test/expects/sass.js | 2 - test/expects/scoped.js | 3 -- test/expects/src.js | 12 ----- test/expects/styl.js | 2 - test/fixtures/custom.vue | 3 -- test/fixtures/empty.vue | 0 test/fixtures/imports/import.less | 1 - test/fixtures/imports/import.sass | 2 - test/fixtures/imports/import.styl | 2 - test/fixtures/jade.vue | 11 ---- test/fixtures/less.vue | 17 ------- test/fixtures/media-query.vue | 7 +++ test/fixtures/multiple-scripts.vue | 7 --- test/fixtures/multiple-styles.vue | 18 ------- test/fixtures/multiple.vue | 33 ------------ test/fixtures/non-minified.vue | 9 ---- test/fixtures/postcss.vue | 5 ++ test/fixtures/pre-processors.vue | 34 +++++++++++++ test/fixtures/pug.vue | 13 ++--- test/fixtures/sass.vue | 8 --- test/fixtures/scoped-css.vue | 20 ++++++++ test/fixtures/scoped.vue | 12 ----- test/fixtures/script-import.js | 7 +++ test/fixtures/script-import.vue | 1 + test/fixtures/src.vue | 3 -- test/fixtures/src/test.js | 3 -- test/fixtures/styl.vue | 7 --- test/fixtures/style-import-scoped.css | 1 + test/fixtures/style-import.css | 1 + test/fixtures/style-import.vue | 2 + test/fixtures/template-import.jade | 2 + test/fixtures/template-import.vue | 1 + test/fixtures/test.html | 1 - test/fixtures/test.styl | 2 - test/test.js | 73 +++++++++++++++++++++++++++ 47 files changed, 159 insertions(+), 254 deletions(-) delete mode 100644 test/expects/autoprefix.js delete mode 100644 test/expects/basic.js delete mode 100644 test/expects/custom.js delete mode 100644 test/expects/empty.js delete mode 100644 test/expects/jade.js delete mode 100644 test/expects/less.js delete mode 100644 test/expects/multiple-scripts.js delete mode 100644 test/expects/multiple-styles.js delete mode 100644 test/expects/multiple.js delete mode 100644 test/expects/non-minified.js delete mode 100644 test/expects/pug.js delete mode 100644 test/expects/sass.js delete mode 100644 test/expects/scoped.js delete mode 100644 test/expects/src.js delete mode 100644 test/expects/styl.js delete mode 100644 test/fixtures/custom.vue delete mode 100644 test/fixtures/empty.vue delete mode 100644 test/fixtures/imports/import.less delete mode 100644 test/fixtures/imports/import.sass delete mode 100644 test/fixtures/imports/import.styl delete mode 100644 test/fixtures/jade.vue delete mode 100644 test/fixtures/less.vue create mode 100644 test/fixtures/media-query.vue delete mode 100644 test/fixtures/multiple-scripts.vue delete mode 100644 test/fixtures/multiple-styles.vue delete mode 100644 test/fixtures/multiple.vue delete mode 100644 test/fixtures/non-minified.vue create mode 100644 test/fixtures/postcss.vue create mode 100644 test/fixtures/pre-processors.vue delete mode 100644 test/fixtures/sass.vue create mode 100644 test/fixtures/scoped-css.vue delete mode 100644 test/fixtures/scoped.vue create mode 100644 test/fixtures/script-import.js create mode 100644 test/fixtures/script-import.vue delete mode 100644 test/fixtures/src.vue delete mode 100644 test/fixtures/src/test.js delete mode 100644 test/fixtures/styl.vue create mode 100644 test/fixtures/style-import-scoped.css create mode 100644 test/fixtures/style-import.css create mode 100644 test/fixtures/style-import.vue create mode 100644 test/fixtures/template-import.jade create mode 100644 test/fixtures/template-import.vue delete mode 100644 test/fixtures/test.html delete mode 100644 test/fixtures/test.styl diff --git a/lib/compiler.js b/lib/compiler.js index b5c5ccd..ac8f61f 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -168,7 +168,7 @@ function processScript (part, filePath, parts) { } function processStyle (part, filePath, id, parts) { - var style = getContent(part) + var style = getContent(part, filePath) return compileAsPromise('style', style, part.lang, filePath) .then(function (res) { return rewriteStyle(id, res, part.scoped).then(function (res) { diff --git a/test/expects/autoprefix.js b/test/expects/autoprefix.js deleted file mode 100644 index 4771cac..0000000 --- a/test/expects/autoprefix.js +++ /dev/null @@ -1,2 +0,0 @@ -var __vueify_insert__ = require("vueify/lib/insert-css") -var __vueify_style__ = __vueify_insert__.insert("body{-webkit-transform:scale(1);transform:scale(1)}") diff --git a/test/expects/basic.js b/test/expects/basic.js deleted file mode 100644 index 1a4337f..0000000 --- a/test/expects/basic.js +++ /dev/null @@ -1,41 +0,0 @@ -var __vueify_insert__ = require("vueify/lib/insert-css") -var __vueify_style__ = __vueify_insert__.insert("html{font-size:20px}") -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck"); - -var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); - -var _createClass2 = require("babel-runtime/helpers/createClass"); - -var _createClass3 = _interopRequireDefault(_createClass2); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var Test = function () { - function Test() { - (0, _classCallCheck3.default)(this, Test); - } - - (0, _createClass3.default)(Test, [{ - key: "ok", - value: function ok() {} - }]); - return Test; -}(); - -var evens = [2, 4, 6, 8]; -var odds = evens.map(function (v) { - return v + 1; -}); -exports.default = { - data: function data() { - return odds; - } -}; -if (module.exports.__esModule) module.exports = module.exports.default -;(typeof module.exports === "function"? module.exports.options: module.exports).template = "

hello

" diff --git a/test/expects/custom.js b/test/expects/custom.js deleted file mode 100644 index 3b3069a..0000000 --- a/test/expects/custom.js +++ /dev/null @@ -1,4 +0,0 @@ - -console.log('ok') - -if (module.exports.__esModule) module.exports = module.exports.default diff --git a/test/expects/empty.js b/test/expects/empty.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/expects/jade.js b/test/expects/jade.js deleted file mode 100644 index 1ad9008..0000000 --- a/test/expects/jade.js +++ /dev/null @@ -1 +0,0 @@ -;(typeof module.exports === "function"? module.exports.options: module.exports).template = "
  • foo
  • bar
  • baz
  • foo
  • bar
  • baz
" diff --git a/test/expects/less.js b/test/expects/less.js deleted file mode 100644 index ea9f0e0..0000000 --- a/test/expects/less.js +++ /dev/null @@ -1,2 +0,0 @@ -var __vueify_insert__ = require("vueify/lib/insert-css") -var __vueify_style__ = __vueify_insert__.insert(".box{color:#fe33ac;border-color:#fdcdea}.box div{-webkit-box-shadow:0 0 5px rgba(0,0,0,.3);box-shadow:0 0 5px rgba(0,0,0,.3)}.box:before{content:'\\f101'}") diff --git a/test/expects/multiple-scripts.js b/test/expects/multiple-scripts.js deleted file mode 100644 index cce2688..0000000 --- a/test/expects/multiple-scripts.js +++ /dev/null @@ -1,12 +0,0 @@ -var b; - -b = x(function() { - return x || 5; -}); - -"use strict"; - -var p = function p(x) { - return x || 5; -}; -if (module.exports.__esModule) module.exports = module.exports.default diff --git a/test/expects/multiple-styles.js b/test/expects/multiple-styles.js deleted file mode 100644 index e02ef0c..0000000 --- a/test/expects/multiple-styles.js +++ /dev/null @@ -1,2 +0,0 @@ -var __vueify_insert__ = require("vueify/lib/insert-css") -var __vueify_style__ = __vueify_insert__.insert("h1{font-size:20px}\n#test h1{font-size:18px}\nh2{font-size:14px}") diff --git a/test/expects/multiple.js b/test/expects/multiple.js deleted file mode 100644 index a677dbc..0000000 --- a/test/expects/multiple.js +++ /dev/null @@ -1,18 +0,0 @@ -var __vueify_insert__ = require("vueify/lib/insert-css") -var __vueify_style__ = __vueify_insert__.insert("body{font:12px Helvetica,Arial,sans-serif}a.button{-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}") -module.exports = { - data: function() { - return { - a: 1, - b: 2 - }; - }, - events: { - 'hook:created': function() { - return console.log('created!'); - } - } -}; - -if (module.exports.__esModule) module.exports = module.exports.default -;(typeof module.exports === "function"? module.exports.options: module.exports).template = "

Jade - node template engine
You are amazing

Jade is a terse and simple templating language with a strong focus on performance and powerful features.

" diff --git a/test/expects/non-minified.js b/test/expects/non-minified.js deleted file mode 100644 index 07c596c..0000000 --- a/test/expects/non-minified.js +++ /dev/null @@ -1,3 +0,0 @@ -var __vueify_insert__ = require("vueify/lib/insert-css") -var __vueify_style__ = __vueify_insert__.insert("\nhtml {\n font-size: 20px;\n}\n") -;(typeof module.exports === "function"? module.exports.options: module.exports).template = "\n

hello

\n" diff --git a/test/expects/pug.js b/test/expects/pug.js deleted file mode 100644 index 1ad9008..0000000 --- a/test/expects/pug.js +++ /dev/null @@ -1 +0,0 @@ -;(typeof module.exports === "function"? module.exports.options: module.exports).template = "
  • foo
  • bar
  • baz
  • foo
  • bar
  • baz
" diff --git a/test/expects/sass.js b/test/expects/sass.js deleted file mode 100644 index bdfc383..0000000 --- a/test/expects/sass.js +++ /dev/null @@ -1,2 +0,0 @@ -var __vueify_insert__ = require("vueify/lib/insert-css") -var __vueify_style__ = __vueify_insert__.insert("body{font:100% Helvetica,sans-serif;color:#333}") diff --git a/test/expects/scoped.js b/test/expects/scoped.js deleted file mode 100644 index b79ecb7..0000000 --- a/test/expects/scoped.js +++ /dev/null @@ -1,3 +0,0 @@ -var __vueify_insert__ = require("vueify/lib/insert-css") -var __vueify_style__ = __vueify_insert__.insert("div[{{id}}]{color:red}.test[{{id}}]{color:green}.test[{{id}}]:after{content:'bye!'}@media print{div[{{id}}]{color:green}}") -;(typeof module.exports === "function"? module.exports.options: module.exports).template = "
hi

bye

" diff --git a/test/expects/src.js b/test/expects/src.js deleted file mode 100644 index ad17b4a..0000000 --- a/test/expects/src.js +++ /dev/null @@ -1,12 +0,0 @@ -var __vueify_insert__ = require("vueify/lib/insert-css") -var __vueify_style__ = __vueify_insert__.insert("h1{font-size:12px}") -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = { - el: '#hi' -}; -if (module.exports.__esModule) module.exports = module.exports.default -;(typeof module.exports === "function"? module.exports.options: module.exports).template = "

hi

" diff --git a/test/expects/styl.js b/test/expects/styl.js deleted file mode 100644 index bdfc383..0000000 --- a/test/expects/styl.js +++ /dev/null @@ -1,2 +0,0 @@ -var __vueify_insert__ = require("vueify/lib/insert-css") -var __vueify_style__ = __vueify_insert__.insert("body{font:100% Helvetica,sans-serif;color:#333}") diff --git a/test/fixtures/custom.vue b/test/fixtures/custom.vue deleted file mode 100644 index e5a016e..0000000 --- a/test/fixtures/custom.vue +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/test/fixtures/empty.vue b/test/fixtures/empty.vue deleted file mode 100644 index e69de29..0000000 diff --git a/test/fixtures/imports/import.less b/test/fixtures/imports/import.less deleted file mode 100644 index 6679fe0..0000000 --- a/test/fixtures/imports/import.less +++ /dev/null @@ -1 +0,0 @@ -@base: #f938ab; diff --git a/test/fixtures/imports/import.sass b/test/fixtures/imports/import.sass deleted file mode 100644 index 6fb403e..0000000 --- a/test/fixtures/imports/import.sass +++ /dev/null @@ -1,2 +0,0 @@ -$font-stack: Helvetica, sans-serif; -$primary-color: #333; diff --git a/test/fixtures/imports/import.styl b/test/fixtures/imports/import.styl deleted file mode 100644 index b08b59b..0000000 --- a/test/fixtures/imports/import.styl +++ /dev/null @@ -1,2 +0,0 @@ -$font-stack = Helvetica, sans-serif; -$primary-color = #333 diff --git a/test/fixtures/jade.vue b/test/fixtures/jade.vue deleted file mode 100644 index 5b44d98..0000000 --- a/test/fixtures/jade.vue +++ /dev/null @@ -1,11 +0,0 @@ - \ No newline at end of file diff --git a/test/fixtures/less.vue b/test/fixtures/less.vue deleted file mode 100644 index 060a45a..0000000 --- a/test/fixtures/less.vue +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/test/fixtures/media-query.vue b/test/fixtures/media-query.vue new file mode 100644 index 0000000..9dbe0ee --- /dev/null +++ b/test/fixtures/media-query.vue @@ -0,0 +1,7 @@ + diff --git a/test/fixtures/multiple-scripts.vue b/test/fixtures/multiple-scripts.vue deleted file mode 100644 index 1ae4119..0000000 --- a/test/fixtures/multiple-scripts.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/test/fixtures/multiple-styles.vue b/test/fixtures/multiple-styles.vue deleted file mode 100644 index 71496f9..0000000 --- a/test/fixtures/multiple-styles.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - - - \ No newline at end of file diff --git a/test/fixtures/multiple.vue b/test/fixtures/multiple.vue deleted file mode 100644 index 1bfbc94..0000000 --- a/test/fixtures/multiple.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - - - \ No newline at end of file diff --git a/test/fixtures/non-minified.vue b/test/fixtures/non-minified.vue deleted file mode 100644 index 0e9ecd0..0000000 --- a/test/fixtures/non-minified.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/test/fixtures/postcss.vue b/test/fixtures/postcss.vue new file mode 100644 index 0000000..a02d550 --- /dev/null +++ b/test/fixtures/postcss.vue @@ -0,0 +1,5 @@ + diff --git a/test/fixtures/pre-processors.vue b/test/fixtures/pre-processors.vue new file mode 100644 index 0000000..f59787e --- /dev/null +++ b/test/fixtures/pre-processors.vue @@ -0,0 +1,34 @@ + + + + + + + + + diff --git a/test/fixtures/pug.vue b/test/fixtures/pug.vue index d1b7643..5a43989 100644 --- a/test/fixtures/pug.vue +++ b/test/fixtures/pug.vue @@ -1,11 +1,6 @@ diff --git a/test/fixtures/sass.vue b/test/fixtures/sass.vue deleted file mode 100644 index 3930c28..0000000 --- a/test/fixtures/sass.vue +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/test/fixtures/scoped-css.vue b/test/fixtures/scoped-css.vue new file mode 100644 index 0000000..ce28b06 --- /dev/null +++ b/test/fixtures/scoped-css.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/test/fixtures/scoped.vue b/test/fixtures/scoped.vue deleted file mode 100644 index d30a9c0..0000000 --- a/test/fixtures/scoped.vue +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/test/fixtures/script-import.js b/test/fixtures/script-import.js new file mode 100644 index 0000000..8ab2015 --- /dev/null +++ b/test/fixtures/script-import.js @@ -0,0 +1,7 @@ +export default { + data () { + return { + msg: 'Hello from Component A!' + } + } +}; \ No newline at end of file diff --git a/test/fixtures/script-import.vue b/test/fixtures/script-import.vue new file mode 100644 index 0000000..b45d1ec --- /dev/null +++ b/test/fixtures/script-import.vue @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/fixtures/src.vue b/test/fixtures/src.vue deleted file mode 100644 index 37d642b..0000000 --- a/test/fixtures/src.vue +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/test/fixtures/src/test.js b/test/fixtures/src/test.js deleted file mode 100644 index dce344e..0000000 --- a/test/fixtures/src/test.js +++ /dev/null @@ -1,3 +0,0 @@ -export default { - el: '#hi' -} diff --git a/test/fixtures/styl.vue b/test/fixtures/styl.vue deleted file mode 100644 index b24d35a..0000000 --- a/test/fixtures/styl.vue +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/test/fixtures/style-import-scoped.css b/test/fixtures/style-import-scoped.css new file mode 100644 index 0000000..954b5d8 --- /dev/null +++ b/test/fixtures/style-import-scoped.css @@ -0,0 +1 @@ +h1 { color: green; } diff --git a/test/fixtures/style-import.css b/test/fixtures/style-import.css new file mode 100644 index 0000000..5ce768c --- /dev/null +++ b/test/fixtures/style-import.css @@ -0,0 +1 @@ +h1 { color: red; } diff --git a/test/fixtures/style-import.vue b/test/fixtures/style-import.vue new file mode 100644 index 0000000..54b83bf --- /dev/null +++ b/test/fixtures/style-import.vue @@ -0,0 +1,2 @@ + + diff --git a/test/fixtures/template-import.jade b/test/fixtures/template-import.jade new file mode 100644 index 0000000..bc60abf --- /dev/null +++ b/test/fixtures/template-import.jade @@ -0,0 +1,2 @@ +div + h1 hello diff --git a/test/fixtures/template-import.vue b/test/fixtures/template-import.vue new file mode 100644 index 0000000..ce53453 --- /dev/null +++ b/test/fixtures/template-import.vue @@ -0,0 +1 @@ + diff --git a/test/fixtures/test.html b/test/fixtures/test.html deleted file mode 100644 index 67326d3..0000000 --- a/test/fixtures/test.html +++ /dev/null @@ -1 +0,0 @@ -

hi

\ No newline at end of file diff --git a/test/fixtures/test.styl b/test/fixtures/test.styl deleted file mode 100644 index c6fe265..0000000 --- a/test/fixtures/test.styl +++ /dev/null @@ -1,2 +0,0 @@ -h1 - font-size 12px \ No newline at end of file diff --git a/test/test.js b/test/test.js index fc23e02..5081c87 100644 --- a/test/test.js +++ b/test/test.js @@ -10,6 +10,7 @@ const browserify = require('browserify') const vueify = require('../index') const jsdom = require('jsdom') const vueCompiler = require('vue-template-compiler') +const genId = require('../lib/gen-id') const tempDir = path.resolve(__dirname, './temp') const mockEntry = path.resolve(tempDir, 'entry.js') @@ -49,4 +50,76 @@ describe('vueify', () => { const style = window.document.querySelector('style').textContent expect(style).to.contain('comp-a h2 {\n color: #f00;\n}') }) + + test('pre-processors', window => { + var module = window.vueModule + assertRenderFn(module, + '
' + + '

This is the app

' + + '' + + '' + + '
' + ) + expect(module.data().msg).to.contain('Hello from coffee!') + var style = window.document.querySelector('style').textContent + // stylus + expect(style).to.contain('body {\n font: 100% Helvetica, sans-serif;\n color: #999;\n}') + // sass + expect(style).to.contain('h1 {\n color: red;') + // less + expect(style).to.contain('h1 {\n color: green;') + }) + + test('pug', window => { + var module = window.vueModule + assertRenderFn(module, + '
' + + '

This is the app

' + + '' + + '' + + '
' + ) + }) + + test('scoped-css', window => { + var module = window.vueModule + var id = 'data-v-' + genId(require.resolve('./fixtures/scoped-css.vue')) + expect(module._scopeId).to.equal(id) + assertRenderFn(module, + '
' + + '

hi

\n' + + '

hi

\n' + + '\n' + + '

' + + '
' + ) + var style = window.document.querySelector('style').textContent + expect(style).to.contain('.test[' + id + '] {\n color: yellow;\n}') + expect(style).to.contain('.test[' + id + ']:after {\n content: \'bye!\';\n}') + expect(style).to.contain('h1[' + id + '] {\n color: green;\n}') + }) + + test('style-import', window => { + var styles = window.document.querySelectorAll('style') + expect(styles[0].textContent).to.contain('h1 { color: red; }') + // import with scoped + var id = 'data-v-' + genId(require.resolve('./fixtures/style-import.vue')) + expect(styles[0].textContent).to.contain('h1[' + id + '] { color: green; }') + }) + + test('template-import', window => { + var module = window.vueModule + assertRenderFn(module, '

hello

') + }) + + test('script-import', window => { + var module = window.vueModule + expect(module.data().msg).to.contain('Hello from Component A!') + }) + + test('media-query', window => { + var style = window.document.querySelector('style').textContent + var id = 'data-v-' + genId(require.resolve('./fixtures/media-query.vue')) + expect(style).to.contain('@media print {\n .foo[' + id + '] {\n color: #000;\n }\n}') + }) }) From 3301ec70a9640d999492602ff00668395fb04e75 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 19:47:59 -0400 Subject: [PATCH 08/52] better template error warnings --- lib/compiler.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index ac8f61f..01ae6c0 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -147,7 +147,10 @@ function processTemplate (part, filePath, parts) { .then(function (res) { var compiled = vueCompiler.compile(res) if (compiled.errors.length) { - throw new Error(compiled.errors.join('\n\n')) + compiled.errors.forEach(function (msg) { + console.error('\n' + chalk.red(msg) + '\n') + }) + throw new Error('Vue template compilation failed') } else { parts.template = { render: toFunction(compiled.render), @@ -190,10 +193,10 @@ function loadSrc (src, filePath) { try { return fs.readFileSync(filePath, 'utf-8') } catch (e) { - console.warn( + console.error(chalk.red( 'Failed to load src: "' + src + '" from file: "' + filePath + '"' - ) + )) } } From 8d6072307ce24119399205a5809b3dc9b8d1fcb3 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 19:48:10 -0400 Subject: [PATCH 09/52] 9.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8d81c92..42b6f4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "8.5.4", + "version": "9.0.0", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From 5909cb92215b4ccbc08e50da0224abb2b4ef2c2e Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 19:49:38 -0400 Subject: [PATCH 10/52] include mkdirp as dep --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 42b6f4c..2ed6a3d 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "jade": "^1.11.0", "jsdom": "^9.2.1", "less": "^2.5.1", + "mkdirp": "^0.5.1", "mocha": "^2.3.3", "node-sass": "^3.3.3", "pug": "^2.0.0-alpha6", From 9666af26f4c805371ce3c2ffcb3f00e897c8980a Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 19:55:40 -0400 Subject: [PATCH 11/52] move changelog into releases --- README.md | 65 +------------------------------------------------------ 1 file changed, 1 insertion(+), 64 deletions(-) diff --git a/README.md b/README.md index da918e0..41f9f4e 100644 --- a/README.md +++ b/README.md @@ -327,70 +327,7 @@ If you use Webpack, there's also [vue-loader](https://github.com/vuejs/vue-loade ## Changelog -### 8.5.0 - -- Now also supports passing in Vueify options via browserify transform options. The options are exactly the same as `vue.config.js`. - -### 8.4.0 - -- Removed peer dependencies. Now vueify simply warns you when you are using a feature that requires a missing dependency. - -### 8.3.0 - -- Added compile-time template syntax validation that catches common errors. -- Code blocks with base indents are now de-indented before being processed. - -### 8.2.0 - -- Added `htmlMinifier` option in config that allows configuration of HTML minification in production mode. -- Fixed HTML minification removing `type` attribute for ``. - -### 8.1.0 - -- Vueify now respects `.babelrc` over default options. - -### 8.0.0 - -- `babel-core` is now a peer dependency. - -### 7.0.0 - -- Added relative `@import` path support and import dependency tracking for LESS, SASS & Stylus. Now you can `@import` files using relative paths to the file being edited, and editing these imported files will also trigger watchify rebuild. - -- Removed built-in compiler for `myth`. Prefer using PostCSS + CSSNext. - -### 6.0.0 - -- Upgraded to Babel 6. This is a breaking change because the babel configuration is now different. - -### 5.0.4 - -- Added `postcss` option for providing custom PostCSS plugins. - -### 5.0.0 - -- New: CSS output is now autoprefixed by default. -- Changed: [New config file format](#configuring-options) - -### 4.0.0 - -- Support ES2015 by default. - -### 3.0.0 - -- Added support for [scoped CSS](#scoped-css) and [component hot reloading](#hot-reload). - -### 2.0.1 - -- Built-in lang for ES2015 has been renamed from `es6` to `es`. - -- `es` transforms now uses loose mode and optional runtime by default. This means in addition to installing `babel`, you should also install `babel-runtime`. - -- Templates and CSS are now non-minified by default. To enable minification, run the build with `NODE_ENV=production`. - -- Options for built-in pre-processors can now be configured in `vue.config.js`. - -- `vue-component-compiler` has been merged into `vueify`. It is now exposed as `require('vueify').compiler`. +For version 9.0.0 and above, please see the [Releases](https://github.com/vuejs/vueify/releases) page for changes in each version. ## License From b26e25ba928c6f79cd673cc21ba6f386e7fff0a4 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 23:27:38 -0400 Subject: [PATCH 12/52] simplify insert-css --- lib/compiler.js | 21 +++++++++++---------- lib/insert-css.js | 9 +++++++-- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index 01ae6c0..e3f3634 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -19,8 +19,10 @@ try { hasBabel = false } +var resolvedPartsCache = Object.create(null) + // determine dynamic script paths -var hotReloadAPIPath = normalize.dep('vue-hot-reload-api') +var hotReloadAPIPath = 'vue-hot-reload-api' //normalize.dep('vue-hot-reload-api') var insertCSSPath = normalize.lib('insert-css') // expose compiler @@ -79,14 +81,19 @@ compiler.compile = function (content, filePath, cb) { .catch(cb) function mergeParts () { + // check whether each part has changed + var prevParts = resolvedPartsCache[id] || {} + resolvedPartsCache[id] = resolvedParts + var scriptChanged = resolvedParts.script !== prevParts.script + var templateChanged = resolvedParts.template !== prevParts.template + var output = '' // styles var style = resolvedParts.styles.join('\n') if (style) { style = JSON.stringify(style) output += - 'var __vueify_insert__ = require("' + insertCSSPath + '")\n' + - 'var __vueify_style__ = __vueify_insert__.insert(' + style + ')\n' + 'var __vueify_style_dispose__ = require("' + insertCSSPath + '").insert(' + style + ')\n' } // script var script = resolvedParts.script @@ -120,13 +127,7 @@ compiler.compile = function (content, filePath, cb) { ' if (!hotAPI.compatible) return\n' + ' module.hot.accept()\n' + // remove style tag on dispose - (style - ? ' module.hot.dispose(function () {\n' + - ' __vueify_insert__.cache[' + style + '] = false\n' + - ' document.head.removeChild(__vueify_style__)\n' + - ' })\n' - : '' - ) + + (style ? ' module.hot.dispose(__vueify_style_dispose__)\n' : '') + ' if (!module.hot.data) {\n' + // initial insert ' hotAPI.createRecord("' + id + '", __vue__options__)\n' + diff --git a/lib/insert-css.js b/lib/insert-css.js index 69130e9..c3d3891 100644 --- a/lib/insert-css.js +++ b/lib/insert-css.js @@ -1,7 +1,9 @@ var inserted = exports.cache = {} +function noop () {} + exports.insert = function (css) { - if (inserted[css]) return + if (inserted[css]) return noop inserted[css] = true var elem = document.createElement('style') @@ -14,5 +16,8 @@ exports.insert = function (css) { } document.getElementsByTagName('head')[0].appendChild(elem) - return elem + return function () { + document.getElementsByTagName('head')[0].removeChild(elem) + inserted[css] = false + } } From 34830f98da82c5f48397f45baf10eebd9d019a6e Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 23:32:04 -0400 Subject: [PATCH 13/52] more granular hot-reload --- lib/compiler.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index e3f3634..ec895dd 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -81,7 +81,7 @@ compiler.compile = function (content, filePath, cb) { .catch(cb) function mergeParts () { - // check whether each part has changed + // check whether script/template has changed var prevParts = resolvedPartsCache[id] || {} resolvedPartsCache[id] = resolvedParts var scriptChanged = resolvedParts.script !== prevParts.script @@ -133,7 +133,12 @@ compiler.compile = function (content, filePath, cb) { ' hotAPI.createRecord("' + id + '", __vue__options__)\n' + ' } else {\n' + // update - ' hotAPI.reload("' + id + '", __vue__options__)\n' + + (scriptChanged + ? ' hotAPI.reload("' + id + '", __vue__options__)\n' + : templateChanged + ? ' hotAPI.rerender("' + id + '", __vue__options__)\n' + : '' + ) + ' }\n' + '})()}' } From daf429460aa9326c5309d887de41b4c216526572 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 23:32:12 -0400 Subject: [PATCH 14/52] 9.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ed6a3d..0fe586c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "9.0.0", + "version": "9.0.1", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From 13291e2a31f19f021580757aa642920d9f0ce726 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 18 Jun 2016 13:38:17 -0400 Subject: [PATCH 15/52] support CSS extraction --- index.js | 7 +++++++ lib/compiler.js | 17 +++++++++++++---- plugins/extract-css.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 plugins/extract-css.js diff --git a/index.js b/index.js index 2e1b3a3..5374cfb 100644 --- a/index.js +++ b/index.js @@ -9,11 +9,16 @@ module.exports = function vueify (file, options) { var data = '' var stream = through(write, end) + stream.vueify = true function dependency(file) { stream.emit('file', file) } + function emitStyle (style) { + stream.emit('vueify-style', style) + } + function write(buf) { data += buf } @@ -21,9 +26,11 @@ module.exports = function vueify (file, options) { function end () { stream.emit('file', file) compiler.on('dependency', dependency) + compiler.on('style', emitStyle) compiler.compile(data, file, function(error, result) { compiler.removeListener('dependency', dependency) + compiler.removeListener('style', emitStyle) if (error) { stream.emit('error', error) // browserify doesn't log the stack by default... diff --git a/lib/compiler.js b/lib/compiler.js index ec895dd..4a8bd74 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -91,9 +91,16 @@ compiler.compile = function (content, filePath, cb) { // styles var style = resolvedParts.styles.join('\n') if (style) { - style = JSON.stringify(style) - output += - 'var __vueify_style_dispose__ = require("' + insertCSSPath + '").insert(' + style + ')\n' + // emit style + compiler.emit('style', { + file: filePath, + style: style + }) + if (!process.env.VUEIFY_EXTRACT_CSS) { + style = JSON.stringify(style) + output += + 'var __vueify_style_dispose__ = require("' + insertCSSPath + '").insert(' + style + ')\n' + } } // script var script = resolvedParts.script @@ -127,7 +134,9 @@ compiler.compile = function (content, filePath, cb) { ' if (!hotAPI.compatible) return\n' + ' module.hot.accept()\n' + // remove style tag on dispose - (style ? ' module.hot.dispose(__vueify_style_dispose__)\n' : '') + + (style && !process.env.VUEIFY_EXTRACT_CSS + ? ' module.hot.dispose(__vueify_style_dispose__)\n' + : '') + ' if (!module.hot.data) {\n' + // initial insert ' hotAPI.createRecord("' + id + '", __vue__options__)\n' + diff --git a/plugins/extract-css.js b/plugins/extract-css.js new file mode 100644 index 0000000..c0d7122 --- /dev/null +++ b/plugins/extract-css.js @@ -0,0 +1,29 @@ +process.env.VUEIFY_EXTRACT_CSS = true + +var fs = require('fs') + +module.exports = function (b, opts) { + var outPath = opts.out || opts.o || 'bundle.css' + var styles = Object.create(null) + + b.on('bundle', function (bs) { + bs.on('end', function () { + fs.writeFile(outPath, Object.keys(styles) + .map(function (file) { return styles[file] }) + .join('\n')) + }) + }) + + b.on('reset', listen) + listen() + + function listen () { + b.on('transform', function (tr, file) { + if (tr.vueify) { + tr.on('vueify-style', function (e) { + styles[e.file] = e.style + }) + } + }) + } +} From a916805df9682e3d40c3f230328c71a0566a5230 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 18 Jun 2016 20:23:31 -0400 Subject: [PATCH 16/52] refactor compiler options --- index.js | 4 +++- lib/compiler.js | 10 ++++++---- lib/compilers/babel.js | 5 ++--- lib/compilers/coffee.js | 5 ++--- lib/compilers/jade.js | 5 ++--- lib/compilers/less.js | 3 +-- lib/compilers/options.js | 1 - lib/compilers/pug.js | 5 ++--- lib/compilers/sass.js | 3 +-- lib/compilers/stylus.js | 3 +-- lib/style-rewriter.js | 4 ++-- plugins/extract-css.js | 5 +++-- 12 files changed, 25 insertions(+), 28 deletions(-) delete mode 100644 lib/compilers/options.js diff --git a/index.js b/index.js index 5374cfb..f072524 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,9 @@ var through = require('through') var compiler = require('./lib/compiler') -compiler.loadConfig() +compiler.loadConfig({ + extractCss: true +}) module.exports = function vueify (file, options) { if (!/.vue$/.test(file)) return through() diff --git a/lib/compiler.js b/lib/compiler.js index 4a8bd74..aa55d7e 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -9,7 +9,6 @@ var vueCompiler = require('vue-template-compiler') var genId = require('./gen-id') var normalize = require('./normalize') var compilers = require('./compilers') -var options = require('./compilers/options') var rewriteStyle = require('./style-rewriter') var hasBabel = true @@ -29,6 +28,9 @@ var insertCSSPath = normalize.lib('insert-css') var compiler = module.exports = new Emitter() compiler.setMaxListeners(Infinity) +// options +var options = compiler.options = {} + // load user config compiler.loadConfig = function () { var fs = require('fs') @@ -96,7 +98,7 @@ compiler.compile = function (content, filePath, cb) { file: filePath, style: style }) - if (!process.env.VUEIFY_EXTRACT_CSS) { + if (!options.extractCSS) { style = JSON.stringify(style) output += 'var __vueify_style_dispose__ = require("' + insertCSSPath + '").insert(' + style + ')\n' @@ -134,7 +136,7 @@ compiler.compile = function (content, filePath, cb) { ' if (!hotAPI.compatible) return\n' + ' module.hot.accept()\n' + // remove style tag on dispose - (style && !process.env.VUEIFY_EXTRACT_CSS + (style && !options.extractCSS ? ' module.hot.dispose(__vueify_style_dispose__)\n' : '') + ' if (!module.hot.data) {\n' + @@ -189,7 +191,7 @@ function processStyle (part, filePath, id, parts) { var style = getContent(part, filePath) return compileAsPromise('style', style, part.lang, filePath) .then(function (res) { - return rewriteStyle(id, res, part.scoped).then(function (res) { + return rewriteStyle(id, res, part.scoped, options).then(function (res) { parts.styles.push(res) }) }) diff --git a/lib/compilers/babel.js b/lib/compilers/babel.js index ebbb7bf..742465b 100644 --- a/lib/compilers/babel.js +++ b/lib/compilers/babel.js @@ -1,6 +1,5 @@ var fs = require('fs') var path = require('path') -var options = require('./options') var ensureRequire = require('../ensure-require') var defaultBabelOptions = { @@ -36,10 +35,10 @@ if (babelOptions === defaultBabelOptions) { } } -module.exports = function (raw, cb) { +module.exports = function (raw, cb, compiler) { try { var babel = require('babel-core') - var res = babel.transform(raw, options.babel || babelOptions) + var res = babel.transform(raw, compiler.options.babel || babelOptions) } catch (err) { return cb(err) } diff --git a/lib/compilers/coffee.js b/lib/compilers/coffee.js index 9f277a8..d0238e1 100644 --- a/lib/compilers/coffee.js +++ b/lib/compilers/coffee.js @@ -1,11 +1,10 @@ -var options = require('./options') var ensureRequire = require('../ensure-require.js') -module.exports = function (raw, cb) { +module.exports = function (raw, cb, compiler) { ensureRequire('coffee', ['coffee-script']) var coffee = require('coffee-script') try { - var js = coffee.compile(raw, options.coffee || { + var js = coffee.compile(raw, compiler.options.coffee || { bare: true }) } catch (err) { diff --git a/lib/compilers/jade.js b/lib/compilers/jade.js index 021e81f..1539816 100644 --- a/lib/compilers/jade.js +++ b/lib/compilers/jade.js @@ -1,11 +1,10 @@ -var options = require('./options') var ensureRequire = require('../ensure-require.js') -module.exports = function (raw, cb) { +module.exports = function (raw, cb, compiler) { ensureRequire('jade', 'jade') var jade = require('jade') try { - var html = jade.compile(raw, options.jade || {})() + var html = jade.compile(raw, compiler.options.jade || {})() } catch (err) { return cb(err) } diff --git a/lib/compilers/less.js b/lib/compilers/less.js index b9d5335..487777d 100644 --- a/lib/compilers/less.js +++ b/lib/compilers/less.js @@ -1,4 +1,3 @@ -var options = require('./options') var assign = require('object-assign') var path = require('path') var ensureRequire = require('../ensure-require.js') @@ -9,7 +8,7 @@ module.exports = function (raw, cb, compiler, filePath) { var opts = assign({ filename: path.basename(filePath) - }, options.less) + }, compiler.options.less) // provide import path var dir = path.dirname(filePath) diff --git a/lib/compilers/options.js b/lib/compilers/options.js deleted file mode 100644 index 4ba52ba..0000000 --- a/lib/compilers/options.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = {} diff --git a/lib/compilers/pug.js b/lib/compilers/pug.js index 7ed9d20..5740b0c 100644 --- a/lib/compilers/pug.js +++ b/lib/compilers/pug.js @@ -1,11 +1,10 @@ -var options = require('./options') var ensureRequire = require('../ensure-require.js') -module.exports = function (raw, cb) { +module.exports = function (raw, cb, compiler) { ensureRequire('pug', 'pug') var pug = require('pug') try { - var html = pug.compile(raw, options.pug || {})() + var html = pug.compile(raw, compiler.options.pug || {})() } catch (err) { return cb(err) } diff --git a/lib/compilers/sass.js b/lib/compilers/sass.js index 4a825c4..f7a8c89 100644 --- a/lib/compilers/sass.js +++ b/lib/compilers/sass.js @@ -1,4 +1,3 @@ -var options = require('./options') var assign = require('object-assign') var path = require('path') var ensureRequire = require('../ensure-require.js') @@ -19,7 +18,7 @@ module.exports = function (raw, cb, compiler, filePath) { error: function (err) { cb(err) } - }, options.sass || { + }, compiler.options.sass || { sourceComments: true }) diff --git a/lib/compilers/stylus.js b/lib/compilers/stylus.js index c63d174..c099ba6 100644 --- a/lib/compilers/stylus.js +++ b/lib/compilers/stylus.js @@ -1,4 +1,3 @@ -var options = require('./options') var assign = require('object-assign') var path = require('path') var ensureRequire = require('../ensure-require.js') @@ -9,7 +8,7 @@ module.exports = function (raw, cb, compiler, filePath) { var opts = assign({ filename: path.basename(filePath) - }, options.stylus || {}) + }, compiler.options.stylus || {}) var dir = path.dirname(filePath) var paths = [dir, process.cwd()] diff --git a/lib/style-rewriter.js b/lib/style-rewriter.js index 17a0250..9881524 100644 --- a/lib/style-rewriter.js +++ b/lib/style-rewriter.js @@ -2,7 +2,6 @@ var postcss = require('postcss') var selectorParser = require('postcss-selector-parser') var cache = require('lru-cache')(100) var assign = require('object-assign') -var options = require('./compilers/options') var currentId var addId = postcss.plugin('add-id', function () { @@ -36,10 +35,11 @@ var addId = postcss.plugin('add-id', function () { * @param {String} id * @param {String} css * @param {Boolean} scoped + * @param {Object} options * @return {Promise} */ -module.exports = function (id, css, scoped) { +module.exports = function (id, css, scoped, options) { var key = id + '!!' + css var val = cache.get(key) if (val) { diff --git a/plugins/extract-css.js b/plugins/extract-css.js index c0d7122..6b05bd7 100644 --- a/plugins/extract-css.js +++ b/plugins/extract-css.js @@ -1,6 +1,7 @@ -process.env.VUEIFY_EXTRACT_CSS = true - var fs = require('fs') +var compiler = require('../lib/compiler') + +compiler.options.extractCSS = true module.exports = function (b, opts) { var outPath = opts.out || opts.o || 'bundle.css' From beedf571f435ee0f4e3ca3531164ab4fb6b73088 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 18 Jun 2016 22:13:24 -0400 Subject: [PATCH 17/52] add source map support --- index.js | 3 ++ lib/compiler.js | 66 +++++++++++++++++++++++++++++++++++++---- lib/compilers/babel.js | 11 +++++-- lib/compilers/coffee.js | 14 +++++++-- package.json | 2 ++ plugins/extract-css.js | 4 ++- 6 files changed, 87 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index f072524..c717627 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,9 @@ compiler.loadConfig({ module.exports = function vueify (file, options) { if (!/.vue$/.test(file)) return through() compiler.applyConfig(options) + compiler.applyConfig({ + sourceMap: options._flags.debug + }) var data = '' var stream = through(write, end) diff --git a/lib/compiler.js b/lib/compiler.js index aa55d7e..181cef5 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -5,12 +5,18 @@ var hash = require('hash-sum') var assign = require('object-assign') var Emitter = require('events').EventEmitter var vueCompiler = require('vue-template-compiler') +var sourceMap = require('source-map') +var convert = require('convert-source-map') var genId = require('./gen-id') var normalize = require('./normalize') var compilers = require('./compilers') var rewriteStyle = require('./style-rewriter') +// determine dynamic script paths +var hotReloadAPIPath = 'vue-hot-reload-api' //normalize.dep('vue-hot-reload-api') +var insertCSSPath = normalize.lib('insert-css') + var hasBabel = true try { require('babel-core') @@ -18,12 +24,9 @@ try { hasBabel = false } +var splitRE = /\r?\n/g var resolvedPartsCache = Object.create(null) -// determine dynamic script paths -var hotReloadAPIPath = 'vue-hot-reload-api' //normalize.dep('vue-hot-reload-api') -var insertCSSPath = normalize.lib('insert-css') - // expose compiler var compiler = module.exports = new Emitter() compiler.setMaxListeners(Infinity) @@ -90,6 +93,7 @@ compiler.compile = function (content, filePath, cb) { var templateChanged = resolvedParts.template !== prevParts.template var output = '' + var map = null // styles var style = resolvedParts.styles.join('\n') if (style) { @@ -107,8 +111,11 @@ compiler.compile = function (content, filePath, cb) { // script var script = resolvedParts.script if (script) { + if (options.sourceMap) { + map = generateSourceMap(script, output) + } output += - ';(function(){' + script + '})()\n' + + ';(function(){\n' + script + '\n})()\n' + // babel 6 compat 'if (module.exports.__esModule) module.exports = module.exports.default\n' } @@ -153,8 +160,46 @@ compiler.compile = function (content, filePath, cb) { ' }\n' + '})()}' } + if (map) { + output += '\n' + convert.fromJSON(map.toString()).toComment() + } cb(null, output) } + + function generateSourceMap (script, output) { + // hot-reload source map busting + var hashedFilename = path.basename(filePath) + '?' + hash(filePath + content) + var map = new sourceMap.SourceMapGenerator() + map.setSourceContent(hashedFilename, content) + // check input source map from babel/coffee etc + var inMap = resolvedParts.map + var inMapConsumer = inMap && new sourceMap.SourceMapConsumer(inMap) + var generatedOffset = (output ? output.split(splitRE).length : 0) + 1 + var originalOffset = content.slice(0, parts.script.start).split(splitRE).length - 1 + script.split(splitRE).forEach(function (line, index) { + var ln = index + 1 + var originalLine = inMapConsumer + ? inMapConsumer.originalPositionFor({ + line: ln, + column: 0 + }).line + : ln + if (originalLine) { + map.addMapping({ + source: hashedFilename, + generated: { + line: ln + generatedOffset, + column: 0 + }, + original: { + line: originalLine + originalOffset, + column: 0 + } + }) + } + }) + return map + } } function processTemplate (part, filePath, parts) { @@ -183,7 +228,12 @@ function processScript (part, filePath, parts) { var script = getContent(part, filePath) return compileAsPromise('script', script, lang, filePath) .then(function (res) { - parts.script = res + if (typeof res === 'string') { + parts.script = res + } else { + parts.script = res.code + parts.map = res.map + } }) } @@ -242,3 +292,7 @@ function compileAsPromise (type, source, lang, filePath) { function toFunction (code) { return 'function(){' + code + '}' } + +function generateSourceMap (script, output, content, parts) { + +} diff --git a/lib/compilers/babel.js b/lib/compilers/babel.js index 742465b..57a676b 100644 --- a/lib/compilers/babel.js +++ b/lib/compilers/babel.js @@ -1,5 +1,6 @@ var fs = require('fs') var path = require('path') +var assign = require('object-assign') var ensureRequire = require('../ensure-require') var defaultBabelOptions = { @@ -35,12 +36,16 @@ if (babelOptions === defaultBabelOptions) { } } -module.exports = function (raw, cb, compiler) { +module.exports = function (raw, cb, compiler, filePath) { try { var babel = require('babel-core') - var res = babel.transform(raw, compiler.options.babel || babelOptions) + var options = assign({ + filename: filePath, + sourceMaps: compiler.options.sourceMap + }, compiler.options.babel || babelOptions) + var res = babel.transform(raw, options) } catch (err) { return cb(err) } - cb(null, res.code) + cb(null, res) } diff --git a/lib/compilers/coffee.js b/lib/compilers/coffee.js index d0238e1..f96b70c 100644 --- a/lib/compilers/coffee.js +++ b/lib/compilers/coffee.js @@ -3,12 +3,20 @@ var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb, compiler) { ensureRequire('coffee', ['coffee-script']) var coffee = require('coffee-script') + var compiled try { - var js = coffee.compile(raw, compiler.options.coffee || { - bare: true + compiled = coffee.compile(raw, compiler.options.coffee || { + bare: true, + sourceMap: compiler.options.sourceMap }) } catch (err) { return cb(err) } - cb(null, js) + if (compiler.options.sourceMap) { + compiled = { + code: compiled.js, + map: compiled.v3SourceMap + } + } + cb(null, compiled) } diff --git a/package.json b/package.json index 0fe586c..4eb6f3e 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,14 @@ "homepage": "https://github.com/vuejs/vueify", "dependencies": { "chalk": "^1.1.1", + "convert-source-map": "^1.2.0", "cssnano": "^3.3.2", "hash-sum": "^1.0.2", "lru-cache": "^4.0.0", "object-assign": "^4.0.1", "postcss": "^5.0.10", "postcss-selector-parser": "^2.0.0", + "source-map": "^0.5.6", "through": "^2.3.6", "vue-hot-reload-api": "^2.0.1", "vue-template-compiler": "^2.0.0-alpha.3" diff --git a/plugins/extract-css.js b/plugins/extract-css.js index 6b05bd7..6f4e649 100644 --- a/plugins/extract-css.js +++ b/plugins/extract-css.js @@ -1,7 +1,9 @@ var fs = require('fs') var compiler = require('../lib/compiler') -compiler.options.extractCSS = true +compiler.applyConfig({ + extractCSS: true +}) module.exports = function (b, opts) { var outPath = opts.out || opts.o || 'bundle.css' From 2e7a2f13bcc6223d85392a8a575a19fae9352b6d Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 18 Jun 2016 22:13:37 -0400 Subject: [PATCH 18/52] remove unused --- lib/compiler.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index 181cef5..2b26766 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -292,7 +292,3 @@ function compileAsPromise (type, source, lang, filePath) { function toFunction (code) { return 'function(){' + code + '}' } - -function generateSourceMap (script, output, content, parts) { - -} From b0621f9ae1f611c3573bf901a5dba52fa12b22fc Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 18 Jun 2016 22:24:04 -0400 Subject: [PATCH 19/52] pad output --- lib/compiler.js | 6 +++--- lib/compilers/babel.js | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index 2b26766..6206803 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -63,7 +63,7 @@ compiler.compile = function (content, filePath, cb) { // generate css scope id var id = 'data-v-' + genId(filePath) // parse the component into parts - var parts = vueCompiler.parseComponent(content) + var parts = vueCompiler.parseComponent(content, { pad: true }) // check for scoped style nodes var hasScopedStyle = parts.styles.some(function (style) { @@ -175,7 +175,6 @@ compiler.compile = function (content, filePath, cb) { var inMap = resolvedParts.map var inMapConsumer = inMap && new sourceMap.SourceMapConsumer(inMap) var generatedOffset = (output ? output.split(splitRE).length : 0) + 1 - var originalOffset = content.slice(0, parts.script.start).split(splitRE).length - 1 script.split(splitRE).forEach(function (line, index) { var ln = index + 1 var originalLine = inMapConsumer @@ -192,7 +191,7 @@ compiler.compile = function (content, filePath, cb) { column: 0 }, original: { - line: originalLine + originalOffset, + line: originalLine, column: 0 } }) @@ -241,6 +240,7 @@ function processStyle (part, filePath, id, parts) { var style = getContent(part, filePath) return compileAsPromise('style', style, part.lang, filePath) .then(function (res) { + res = res.trim() return rewriteStyle(id, res, part.scoped, options).then(function (res) { parts.styles.push(res) }) diff --git a/lib/compilers/babel.js b/lib/compilers/babel.js index 57a676b..d999bfa 100644 --- a/lib/compilers/babel.js +++ b/lib/compilers/babel.js @@ -40,6 +40,7 @@ module.exports = function (raw, cb, compiler, filePath) { try { var babel = require('babel-core') var options = assign({ + comments: false, filename: filePath, sourceMaps: compiler.options.sourceMap }, compiler.options.babel || babelOptions) From 8350490ea6387c030d2e53b5d81218444b77c9cb Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 18 Jun 2016 23:32:47 -0400 Subject: [PATCH 20/52] update readme --- README.md | 87 ++++++++++++++++--------------------------------------- 1 file changed, 25 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 41f9f4e..25eb4b7 100644 --- a/README.md +++ b/README.md @@ -67,17 +67,6 @@ npm install vueify --save-dev browserify -t vueify -e src/main.js -o build/build.js ``` -If you are using npm 3+, it no longer auto install the peer dependencies. So you will also have to also install the babel-related dependencies: - -``` bash -npm install\ - babel-core\ - babel-preset-es2015\ - babel-runtime\ - babel-plugin-transform-runtime\ - --save-dev -``` - And this is all you need to do in your main entry file: ``` js @@ -86,9 +75,9 @@ var Vue = require('vue') var App = require('./app.vue') new Vue({ - el: 'body', - components: { - app: App + el: '#app', + render: function (createElement) { + return createElement(App) } }) ``` @@ -97,7 +86,7 @@ In your HTML: ``` html - +
``` @@ -121,35 +110,34 @@ Make sure to have the `NODE_ENV` environment variable set to `"production"` when If you are using Gulp, note that `gulp --production` **does not** affect vueify; you still need to explicitly set `NODE_ENV=production`. -## ES2015 by Default - -Vueify automatically transforms the JavaScript in your `*.vue` components using Babel. Write ES2015 today! +## ES2015 with Babel -The default Babel (6) options used for Vue.js components are: +Vueify is pre-configured to work with Babel. Simply install Babel-related dependencies: -``` js -{ - "presets": ["es2015"], - "plugins": ["transform-runtime"] -} +``` bash +npm install\ + babel-core\ + babel-preset-es2015\ + --save-dev ``` -If you wish to override this, you can add a `.babelrc` file at the root of your project: +Then create a `.babelrc`: ``` json { - "presets": ["es2015", "stage-2"], - "plugins": ["transform-runtime"] + "presets": ["es2015"] } ``` +And voila! You can now write ES2015 in your `*.vue` files. Note if you want to use ES2015 on normal `*.js` files, you will also need [babelify](https://github.com/babel/babelify). + You can also configure babel with the `babel` field in `vue.config.js`, which will take the highest priority. -## Enabling Pre-Processors +## Enabling Other Pre-Processors -You need to install the corresponding node modules to enable the compilation. e.g. to get stylus compiled in your Vue components, do `npm install stylus --save-dev`. +For other pre-processors, you also need to install the corresponding node modules to enable the compilation. e.g. to get stylus compiled in your Vue components, do `npm install stylus --save-dev`. -These are the built-in preprocessors: +These are the preprocessors supported by vueify out of the box: - stylus - less @@ -158,13 +146,9 @@ These are the built-in preprocessors: - pug - coffee-script (use `coffee` in [config section](#configuring-options)) -## Autoprefix by Default - -Starting in 5.0.0, all CSS output via vueify will be autoprefixed by default. See [config section](#configuring-options) below on customizing the options. - ## PostCSS -Vueify uses PostCSS for scoped CSS rewrite and autoprefixing. You can also provide your own PostCSS plugins! See [config section](#configuring-options) below for an example. +Vueify uses PostCSS for scoped CSS rewrite. You can also provide your own PostCSS plugins! See [config section](#configuring-options) below for an example. ## Configuring Options @@ -178,15 +162,6 @@ module.exports = { }, // provide your own postcss plugins postcss: [...], - // configure autoprefixer - autoprefixer: { - browsers: ['last 2 versions'] - }, - // configure html minification in production mode - // see https://github.com/kangax/html-minifier#options-quick-reference - htmlMinifier: { - // ... - }, // register custom compilers customCompilers: { // for tags with lang="ts" @@ -209,9 +184,7 @@ Example using custom PostCSS plugin: var cssnext = require('cssnext') module.exports = { - postcss: [cssnext()], - // disable autoprefixer since cssnext comes with it - autoprefixer: false + postcss: [cssnext()] } ``` @@ -253,8 +226,6 @@ browserify('./main.js') ### Scoped CSS -> Experimental - When a ` diff --git a/test/test.js b/test/test.js index 5081c87..69d3e4b 100644 --- a/test/test.js +++ b/test/test.js @@ -3,7 +3,6 @@ process.env.VUEIFY_TEST = true const fs = require('fs') const path = require('path') const expect = require('chai').expect -const hash = require('hash-sum') const rimraf = require('rimraf') const mkdirp = require('mkdirp') const browserify = require('browserify') @@ -37,6 +36,18 @@ function test (file, assert) { }) } +function testCssExtract (file, assert) { + it(file, done => { + fs.writeFileSync(mockEntry, 'window.vueModule = require("../fixtures/' + file + '.vue")') + browserify(mockEntry) + .transform(vueify) + .plugin('./plugins/extract-css', { out: { write: assert, end: done }}) + .bundle((err, buf) => { + if (err) return done(err) + }) + }) +} + function assertRenderFn (options, template) { const compiled = vueCompiler.compile(template) expect(options.render.toString()).to.equal('function (){' + compiled.render + '}') @@ -122,4 +133,8 @@ describe('vueify', () => { var id = 'data-v-' + genId(require.resolve('./fixtures/media-query.vue')) expect(style).to.contain('@media print {\n .foo[' + id + '] {\n color: #000;\n }\n}') }) + + testCssExtract('style-export', css => { + expect(css).to.equal('h2 {color: red;}') + }) }) From 1b2659a1f87b8a8878135477641e00fd45ee42c2 Mon Sep 17 00:00:00 2001 From: Darius Tall Date: Fri, 24 Jun 2016 10:25:08 -0400 Subject: [PATCH 26/52] Add the ability to specify other postcss options (#99) * Add the ability to specify other postcss options * Fixed usage of postcss --- lib/style-rewriter.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/style-rewriter.js b/lib/style-rewriter.js index 9881524..c631857 100644 --- a/lib/style-rewriter.js +++ b/lib/style-rewriter.js @@ -45,9 +45,16 @@ module.exports = function (id, css, scoped, options) { if (val) { return Promise.resolve(val) } else { - var plugins = options.postcss - ? options.postcss.slice() - : [] + var plugins = [] + var opts = {} + + if (options.postcss instanceof Array) { + plugins = options.postcss.slice() + } else if (options.postcss instanceof Object) { + plugins = options.postcss.plugins || [] + opts = options.postcss.options + } + // scoped css rewrite if (scoped) { plugins.push(addId) @@ -60,10 +67,11 @@ module.exports = function (id, css, scoped, options) { } currentId = id return postcss(plugins) - .process(css) + .process(css, opts) .then(function (res) { cache.set(key, res.css) return res.css }) } } + From 34ccdd5bc32aa78a6f26ae6f67677d2418a3efd2 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 24 Jun 2016 10:26:57 -0400 Subject: [PATCH 27/52] 9.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ecd6cb9..44c4723 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "9.1.0", + "version": "9.2.0", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From ab3866334c58d4256c802b7cf8ae3b67b5e65504 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 28 Jun 2016 15:05:43 -0400 Subject: [PATCH 28/52] add functional component warning --- lib/compiler.js | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/compiler.js b/lib/compiler.js index 4bf8f50..7fb0e2c 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -126,6 +126,13 @@ compiler.compile = function (content, filePath, cb) { // template var template = resolvedParts.template if (template) { + if (process.env.NODE_ENV !== 'production') { + output += + 'if (__vue__options__.functional) {console.error("' + + '[vueify] functional components are not supported and ' + + 'should be defined in plain js files using render functions.' + + '")}\n' + } output += '__vue__options__.render = ' + template.render + '\n' + '__vue__options__.staticRenderFns = ' + template.staticRenderFns + '\n' diff --git a/package.json b/package.json index 44c4723..3e65649 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "source-map": "^0.5.6", "through": "^2.3.6", "vue-hot-reload-api": "^2.0.1", - "vue-template-compiler": "^2.0.0-alpha.3" + "vue-template-compiler": "^2.0.0-alpha.8" }, "devDependencies": { "babel-core": "^6.0.0", From dc6de0be8a2854fb91a0b198f7e540bc03e159fa Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 28 Jun 2016 15:05:48 -0400 Subject: [PATCH 29/52] 9.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3e65649..291f3c8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "9.2.0", + "version": "9.2.1", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From cda407d2b69fe543f5225639118dbb738b478eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDiga=20Vidic?= Date: Wed, 29 Jun 2016 18:43:44 -0700 Subject: [PATCH 30/52] Don't make .babelrc a requirement. (#103) * Don't make .babelrc a requirement. If you don't have a .babelrc file in your project you still get babel warning: "You are trying to use "babel". babel-preset-es2015, babel-runtime and babel-plugin-transform-runtime are missing." * Move only comparison to exported function. --- lib/compilers/babel.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/compilers/babel.js b/lib/compilers/babel.js index d999bfa..d237ed6 100644 --- a/lib/compilers/babel.js +++ b/lib/compilers/babel.js @@ -23,20 +23,20 @@ function getBabelRc () { return rc } -if (babelOptions === defaultBabelOptions) { - try { - ensureRequire('babel', ['babel-preset-es2015', 'babel-runtime', 'babel-plugin-transform-runtime']) - } catch (e) { - console.error(e.message) - console.error( - '\n^^^ You are seeing this because you are using Vueify\'s default babel ' + - 'configuration. You can override this with .babelrc or the babel option ' + - 'in vue.config.js.' - ) +module.exports = function (raw, cb, compiler, filePath) { + if (babelOptions === defaultBabelOptions) { + try { + ensureRequire('babel', ['babel-preset-es2015', 'babel-runtime', 'babel-plugin-transform-runtime']) + } catch (e) { + console.error(e.message) + console.error( + '\n^^^ You are seeing this because you are using Vueify\'s default babel ' + + 'configuration. You can override this with .babelrc or the babel option ' + + 'in vue.config.js.' + ) + } } -} -module.exports = function (raw, cb, compiler, filePath) { try { var babel = require('babel-core') var options = assign({ From 8c5e9ed3f992a16fcb82c8c86522eebc01399f02 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 29 Jun 2016 21:45:16 -0400 Subject: [PATCH 31/52] 9.2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 291f3c8..5be8f1a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "9.2.1", + "version": "9.2.2", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From 68694e9d94f3537af243eb8bd30e878f4bd89114 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 30 Jun 2016 10:27:21 -0400 Subject: [PATCH 32/52] add a note about building for production --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 66fa388..949599a 100644 --- a/README.md +++ b/README.md @@ -294,6 +294,14 @@ browserify('./main.js') This only works for vueify 9+. For Vue 1.x / vueify 8.x you can use [vueify-extract-css](https://github.com/rawcreative/vueify-extract-css). +## Building for Production + +When building for production, follow these steps to ensure smaller bundle size: + +1. Make sure `process.env.NODE_ENV === "production"`. This tells `vueify` to avoid including hot-reload related code. + +2. Apply a global [envify](https://github.com/hughsk/envify) transform to your bundle. This allows the minifier to strip out all the warnings in Vue's source code wrapped in env variable conditional blocks. + ## Compiler API The compiler API (originally `vue-component-compiler`) is also exposed: From 8550260612de4338714802fd014cc5f7dfc84dbf Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 30 Jun 2016 10:33:53 -0400 Subject: [PATCH 33/52] skip css and hot-reload in server mode --- lib/compiler.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index 7fb0e2c..d743004 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -60,6 +60,10 @@ compiler.applyConfig = function (config) { } compiler.compile = function (content, filePath, cb) { + var isProduction = process.env.NODE_ENV === 'production' + var isServer = process.env.VUE_ENV === 'server' + var isTest = !!process.env.VUEIFY_TEST + // generate css scope id var id = 'data-v-' + genId(filePath) // parse the component into parts @@ -96,7 +100,7 @@ compiler.compile = function (content, filePath, cb) { var map = null // styles var style = resolvedParts.styles.join('\n') - if (style) { + if (style && !isServer) { // emit style compiler.emit('style', { file: filePath, @@ -126,7 +130,7 @@ compiler.compile = function (content, filePath, cb) { // template var template = resolvedParts.template if (template) { - if (process.env.NODE_ENV !== 'production') { + if (!isProduction && !isServer) { output += 'if (__vue__options__.functional) {console.error("' + '[vueify] functional components are not supported and ' + @@ -142,7 +146,7 @@ compiler.compile = function (content, filePath, cb) { output += '__vue__options__._scopeId = "' + id + '"\n' } // hot reload - if (process.env.NODE_ENV !== 'production' && !process.env.VUEIFY_TEST) { + if (!isProduction && !isTest && !isServer) { output += 'if (module.hot) {(function () {' + ' var hotAPI = require("' + hotReloadAPIPath + '")\n' + From b527242e57aaeda6a19f6a5ad0823eb11ccd2ae6 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 30 Jun 2016 10:33:59 -0400 Subject: [PATCH 34/52] 9.2.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5be8f1a..d012e33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "9.2.2", + "version": "9.2.3", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From bd6c09400b36741f3c7f05cc0156e4b9bd493bd5 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 15 Jul 2016 18:25:59 -0400 Subject: [PATCH 35/52] map all render errors to the template --- lib/compiler.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/compiler.js b/lib/compiler.js index d743004..cde3d99 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -137,9 +137,16 @@ compiler.compile = function (content, filePath, cb) { 'should be defined in plain js files using render functions.' + '")}\n' } + var beforeLines + if (map) { + beforeLines = output.split(splitRE).length + } output += '__vue__options__.render = ' + template.render + '\n' + '__vue__options__.staticRenderFns = ' + template.staticRenderFns + '\n' + if (map) { + addTemplateMapping(content, parts, output, map, beforeLines) + } } // scoped CSS id if (hasScopedStyle) { @@ -205,10 +212,29 @@ compiler.compile = function (content, filePath, cb) { }) } }) + map._hashedFilename = hashedFilename return map } } +function addTemplateMapping (content, parts, output, map, beforeLines) { + var afterLines = output.split(splitRE).length + var templateLine = content.slice(0, parts.template.start).split(splitRE).length + for (; beforeLines < afterLines; beforeLines++) { + map.addMapping({ + source: map._hashedFilename, + generated: { + line: beforeLines, + column: 0 + }, + original: { + line: templateLine, + column: 0 + } + }) + } +} + function processTemplate (part, filePath, parts) { if (!part) return Promise.resolve() var template = getContent(part, filePath) From a3465bb9d6bc695b0f70ba8f096d4c95c033d3cb Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 15 Jul 2016 18:26:03 -0400 Subject: [PATCH 36/52] 9.2.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d012e33..cc3bbde 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "9.2.3", + "version": "9.2.4", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From 62236436086e0d2fc76caf608b9c4f25540970ca Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 28 Sep 2016 19:13:20 -0400 Subject: [PATCH 37/52] add version notice --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 949599a..809c89e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ > [Browserify](http://browserify.org/) transform for [Vue.js](http://vuejs.org/) components, with scoped CSS and component hot-reloading. +**NOTE: master branch now hosts version ^9.0, which only works with Vue ^2.0. Vueify 8.x which works with Vue 1.x is in the [8.x branch](https://github.com/vuejs/vueify/tree/8.x).** + This transform allows you to write your components in this format: ``` html From 9ce0fb10af26b108317c5913ee4549445cff7b0e Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 28 Sep 2016 20:12:53 -0400 Subject: [PATCH 38/52] fix dep --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index cc3bbde..1d8e9a6 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "coffee-script": "^1.10.0", "eslint": "^2.13.0", "eslint-config-vue": "^1.0.3", + "eslint-plugin-html": "^1.5.3", "jade": "^1.11.0", "jsdom": "^9.2.1", "less": "^2.5.1", From fa235bd345779e52d7697c476de9a4393bc394e1 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 12 Nov 2016 11:07:12 -0500 Subject: [PATCH 39/52] include vue-template-es2015-compiler --- lib/template-compiler.js | 3 ++- package.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/template-compiler.js b/lib/template-compiler.js index 3824c37..51314b9 100644 --- a/lib/template-compiler.js +++ b/lib/template-compiler.js @@ -1,5 +1,6 @@ var chalk = require('chalk') var vueCompiler = require('vue-template-compiler') +var transpile = require('vue-template-es2015-compiler') module.exports = function compileTemplate (template, compiler) { var compiled = vueCompiler.compile(template) @@ -17,5 +18,5 @@ module.exports = function compileTemplate (template, compiler) { } function toFunction (code) { - return 'function(){' + code + '}' + return transpile('function render () {' + code + '}') } diff --git a/package.json b/package.json index 1d8e9a6..db1dfae 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "source-map": "^0.5.6", "through": "^2.3.6", "vue-hot-reload-api": "^2.0.1", - "vue-template-compiler": "^2.0.0-alpha.8" + "vue-template-compiler": "^2.0.0-alpha.8", + "vue-template-es2015-compiler": "^1.2.2" }, "devDependencies": { "babel-core": "^6.0.0", From 97741fde0f6099ece99a07a6ef39d4283637642f Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 12 Nov 2016 11:09:32 -0500 Subject: [PATCH 40/52] fix tests --- test/test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index 69d3e4b..dfcf92a 100644 --- a/test/test.js +++ b/test/test.js @@ -9,6 +9,7 @@ const browserify = require('browserify') const vueify = require('../index') const jsdom = require('jsdom') const vueCompiler = require('vue-template-compiler') +const transpile = require('vue-template-es2015-compiler') const genId = require('../lib/gen-id') const tempDir = path.resolve(__dirname, './temp') @@ -50,7 +51,7 @@ function testCssExtract (file, assert) { function assertRenderFn (options, template) { const compiled = vueCompiler.compile(template) - expect(options.render.toString()).to.equal('function (){' + compiled.render + '}') + expect(options.render.toString()).to.equal(transpile('function render() {' + compiled.render + '}')) } describe('vueify', () => { From 357f5818ccd968e98dfedfc6fb6b8a37726a0cdc Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 12 Nov 2016 11:10:02 -0500 Subject: [PATCH 41/52] 9.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index db1dfae..4e0796a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "9.2.4", + "version": "9.3.0", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From 4e9eea85edd75dae080060ef7e9c693079c8b24c Mon Sep 17 00:00:00 2001 From: Adam Niederer Date: Thu, 8 Dec 2016 15:05:47 -0500 Subject: [PATCH 42/52] Load configuration from vue.config.js (#146) Resolves #116 and #145 --- index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/index.js b/index.js index 1bb2933..d789a83 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,7 @@ module.exports = function vueify (file, options) { return through() } + compiler.loadConfig() compiler.applyConfig(options) compiler.applyConfig({ sourceMap: options._flags.debug From f77be6258c6fc47e8bd1af69c5724a179c8c1ab9 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 8 Dec 2016 15:06:15 -0500 Subject: [PATCH 43/52] Fixed Node deprecated warning (#163) --- plugins/extract-css.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/extract-css.js b/plugins/extract-css.js index 740bb80..1b83eb6 100644 --- a/plugins/extract-css.js +++ b/plugins/extract-css.js @@ -18,7 +18,7 @@ module.exports = function (b, opts) { outPath.write(css) outPath.end() } else if (typeof outPath === 'string') { - fs.writeFile(outPath, css) + fs.writeFile(outPath, css, function () {}) } }) }) From 620e90e44ad779355fcd1150305fbcd3676e5567 Mon Sep 17 00:00:00 2001 From: Daniel Diekmeier Date: Thu, 8 Dec 2016 21:06:27 +0100 Subject: [PATCH 44/52] Fix link to browserify-simple (#155) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 809c89e..e55b78c 100644 --- a/README.md +++ b/README.md @@ -271,7 +271,7 @@ npm install browserify-hmr --save-dev watchify -p browserify-hmr index.js -o bundle.js ``` -You can scaffold a hot-reload enabled project easily using `vue-cli` and the [this template](https://github.com/vuejs-templates/browserify-simple-2.0). +You can scaffold a hot-reload enabled project easily using `vue-cli` and the [this template](https://github.com/vuejs-templates/browserify-simple). ## CSS Extraction From f25fb22856b762ca0eb0b82f49810fb55165dcae Mon Sep 17 00:00:00 2001 From: Daniel Diekmeier Date: Thu, 8 Dec 2016 21:08:49 +0100 Subject: [PATCH 45/52] Fix errors with scoped modules (#154) --- lib/style-rewriter.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/style-rewriter.js b/lib/style-rewriter.js index c631857..1195799 100644 --- a/lib/style-rewriter.js +++ b/lib/style-rewriter.js @@ -40,7 +40,7 @@ var addId = postcss.plugin('add-id', function () { */ module.exports = function (id, css, scoped, options) { - var key = id + '!!' + css + var key = id + '!!' + scoped + '!!' + css var val = cache.get(key) if (val) { return Promise.resolve(val) @@ -56,9 +56,16 @@ module.exports = function (id, css, scoped, options) { } // scoped css rewrite - if (scoped) { + // make sure the addId plugin is only pushed once + if (scoped && plugins.indexOf(addId) === -1) { plugins.push(addId) } + + // remove the addId plugin if the style block is not scoped + if (!scoped && plugins.indexOf(addId) !== -1) { + plugins.splice(plugins.indexOf(addId), 1) + } + // minification if (process.env.NODE_ENV === 'production') { plugins.push(require('cssnano')(assign({ From 1c2dce72248b36869b4144207f16da2e28f170bd Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 9 Dec 2016 04:10:25 +0800 Subject: [PATCH 46/52] use hash-sum for module id generation (#160) --- lib/gen-id.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/gen-id.js b/lib/gen-id.js index 25281ae..8c9621d 100644 --- a/lib/gen-id.js +++ b/lib/gen-id.js @@ -1,8 +1,8 @@ // utility for generating a uid for each component file // used in scoped CSS rewriting -var fileUid = 1 -var fileRegistry = Object.create(null) +var hash = require('hash-sum') +var cache = Object.create(null) module.exports = function genId (file) { - return fileRegistry[file] || (fileRegistry[file] = fileUid++) + return cache[file] || (cache[file] = hash(file)) } From 79793efcbc8a33af2162bfee784e7aac5141065a Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 9 Dec 2016 04:11:28 +0800 Subject: [PATCH 47/52] Parse babelrc with json5 (#161) * Parse babelrc with json5 * Include json5 in package.json --- lib/compilers/babel.js | 3 ++- package.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/compilers/babel.js b/lib/compilers/babel.js index d237ed6..323b23d 100644 --- a/lib/compilers/babel.js +++ b/lib/compilers/babel.js @@ -1,5 +1,6 @@ var fs = require('fs') var path = require('path') +var json = require('json5') var assign = require('object-assign') var ensureRequire = require('../ensure-require') @@ -16,7 +17,7 @@ var babelOptions = fs.existsSync(babelRcPath) function getBabelRc () { var rc try { - rc = JSON.parse(fs.readFileSync(babelRcPath, 'utf-8')) + rc = json.parse(fs.readFileSync(babelRcPath, 'utf-8')) } catch (e) { throw new Error('[vueify] Your .babelrc seems to be incorrectly formatted.') } diff --git a/package.json b/package.json index 4e0796a..8aaba5f 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "postcss-selector-parser": "^2.0.0", "source-map": "^0.5.6", "through": "^2.3.6", + "json5": "^0.5.1", "vue-hot-reload-api": "^2.0.1", "vue-template-compiler": "^2.0.0-alpha.8", "vue-template-es2015-compiler": "^1.2.2" From 6c518d597385bab54d330482fd87835337626a85 Mon Sep 17 00:00:00 2001 From: Daniel Diekmeier Date: Thu, 8 Dec 2016 21:21:47 +0100 Subject: [PATCH 48/52] Remove listener leading to memory leak (#156) --- plugins/extract-css.js | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/plugins/extract-css.js b/plugins/extract-css.js index 1b83eb6..e3331e9 100644 --- a/plugins/extract-css.js +++ b/plugins/extract-css.js @@ -23,16 +23,11 @@ module.exports = function (b, opts) { }) }) - b.on('reset', listen) - listen() - - function listen () { - b.on('transform', function (tr, file) { - if (tr.vueify) { - tr.on('vueify-style', function (e) { - styles[e.file] = e.style - }) - } - }) - } + b.on('transform', function (tr, file) { + if (tr.vueify) { + tr.on('vueify-style', function (e) { + styles[e.file] = e.style + }) + } + }) } From 80e168ae34f9feee2eca5d76e386681442710753 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 8 Dec 2016 15:22:26 -0500 Subject: [PATCH 49/52] 9.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8aaba5f..c364b45 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "9.3.0", + "version": "9.4.0", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From 6992fc75de03b394d23b20983d08a6b81596a140 Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Thu, 9 Mar 2017 11:42:31 +0900 Subject: [PATCH 50/52] Fix: invalid warning about babel (#183) --- lib/compilers/babel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compilers/babel.js b/lib/compilers/babel.js index 323b23d..be317b4 100644 --- a/lib/compilers/babel.js +++ b/lib/compilers/babel.js @@ -25,7 +25,7 @@ function getBabelRc () { } module.exports = function (raw, cb, compiler, filePath) { - if (babelOptions === defaultBabelOptions) { + if ((compiler.options.babel || babelOptions) === defaultBabelOptions) { try { ensureRequire('babel', ['babel-preset-es2015', 'babel-runtime', 'babel-plugin-transform-runtime']) } catch (e) { From 8d3159ff7d41bfaf1662056436a4252ea07219aa Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 9 Mar 2017 10:42:56 +0800 Subject: [PATCH 51/52] 9.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c364b45..c1caee7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "9.4.0", + "version": "9.4.1", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From 0bcabf17b6c44cbe0e4c4ff85e3c79d22a853bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20L=C3=BCnborg?= Date: Tue, 25 Dec 2018 23:58:40 +0100 Subject: [PATCH 52/52] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e55b78c..9a42c15 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -# vueify [![Build Status](https://circleci.com/gh/vuejs/vueify.svg?style=shield)](https://circleci.com/gh/vuejs/vueify) [![npm version](https://badge.fury.io/js/vueify.svg)](http://badge.fury.io/js/vueify) +# THIS REPOSITORY IS DEPRECATED + +> Note: We are concentrating our efforts on supporting webpack and rollup. + +## vueify [![Build Status](https://circleci.com/gh/vuejs/vueify.svg?style=shield)](https://circleci.com/gh/vuejs/vueify) [![npm version](https://badge.fury.io/js/vueify.svg)](http://badge.fury.io/js/vueify) > [Browserify](http://browserify.org/) transform for [Vue.js](http://vuejs.org/) components, with scoped CSS and component hot-reloading.