From d8e56147b36afd2aa82c9ebb54507dd57270304f Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 3 May 2016 13:07:29 -0400 Subject: [PATCH 01/69] update babel deps --- package.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index c0d0bf4..71262c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "8.4.0", + "version": "8.4.1", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { @@ -37,18 +37,18 @@ "vue-template-validator": "^1.0.1" }, "peerDependencies": { - "vueify-insert-css": "^1.0.0", - "babel-core": "^6.1.2", - "babel-runtime": "^5.8.0", - "babel-preset-es2015": "^6.1.2", - "babel-plugin-transform-runtime": "^6.1.2", - "vue-hot-reload-api": "^1.2.0" + "babel-core": "^6.8.0", + "babel-runtime": "^6.0.0", + "babel-preset-es2015": "^6.6.0", + "babel-plugin-transform-runtime": "^6.8.0", + "vue-hot-reload-api": "^1.2.0", + "vueify-insert-css": "^1.0.0" }, "devDependencies": { - "babel-core": "^6.1.2", - "babel-plugin-transform-runtime": "^6.1.2", - "babel-preset-es2015": "^6.1.2", - "babel-runtime": "^5.8.0", + "babel-core": "^6.8.0", + "babel-runtime": "^6.0.0", + "babel-preset-es2015": "^6.6.0", + "babel-plugin-transform-runtime": "^6.6.1", "coffee-script": "^1.10.0", "jade": "^1.11.0", "less": "^2.5.1", From 60462897d266ebcc7d54890e85f17eb2a803435b Mon Sep 17 00:00:00 2001 From: Paul Pflugradt Date: Thu, 5 May 2016 01:11:55 +0200 Subject: [PATCH 02/69] Only require babel when used (#82) --- 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 613153a..129bec4 100644 --- a/lib/compilers/babel.js +++ b/lib/compilers/babel.js @@ -1,8 +1,8 @@ var options = require('./options') -var babel = require('babel-core') module.exports = function (raw, cb) { try { + var babel = require('babel-core') var res = babel.transform(raw, options.babel || {}) } catch (err) { return cb(err) From 7683c39b5d2f2b3e92881b01de4129b6f611bd77 Mon Sep 17 00:00:00 2001 From: Paul Pflugradt Date: Thu, 5 May 2016 21:54:43 +0200 Subject: [PATCH 03/69] add advanced dependency checking (fixes #81) (#83) * added advanced dependency checking for babel as an example * fixes * fixed babel-runtime require * replaced peerDependencies with checks & warning for missing modules * bugfix * spelling * added test for missing dependencies --- lib/compiler.js | 3 +++ lib/compilers/babel.js | 2 ++ lib/compilers/coffee.js | 8 +++----- lib/compilers/jade.js | 8 +++----- lib/compilers/less.js | 8 +++----- lib/compilers/pug.js | 8 +++----- lib/compilers/sass.js | 8 +++----- lib/compilers/stylus.js | 8 +++----- lib/ensure-require.js | 32 ++++++++++++++++++++++++++++++++ package.json | 13 +++---------- test/test.js | 11 +++++++++++ 11 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 lib/ensure-require.js diff --git a/lib/compiler.js b/lib/compiler.js index 84499d0..80cdc47 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -12,6 +12,7 @@ var chalk = require('chalk') var assign = require('object-assign') var deindent = require('de-indent') var Emitter = require('events').EventEmitter +var ensureRequire = require('./ensure-require.js') var htmlMinifyOptions = { collapseWhitespace: true, @@ -110,6 +111,7 @@ compiler.compile = function (content, filePath, cb) { // styles var style = extract(parts, 'style') if (style) { + ensureRequire('styles','vueify-insert-css') style = JSON.stringify(style) output += 'var __vueify_style__ = require("vueify-insert-css").insert(' + style + ')\n' @@ -132,6 +134,7 @@ compiler.compile = function (content, filePath, cb) { } // hot reload if (process.env.NODE_ENV !== 'production' && !process.env.VUEIFY_TEST) { + ensureRequire('hot-reload','vue-hot-reload-api') output += 'if (module.hot) {(function () {' + ' module.hot.accept()\n' + diff --git a/lib/compilers/babel.js b/lib/compilers/babel.js index 129bec4..538decc 100644 --- a/lib/compilers/babel.js +++ b/lib/compilers/babel.js @@ -1,6 +1,8 @@ var options = require('./options') +var ensureRequire = require('../ensure-require.js') 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 || {}) diff --git a/lib/compilers/coffee.js b/lib/compilers/coffee.js index fe836fe..4f5dffa 100644 --- a/lib/compilers/coffee.js +++ b/lib/compilers/coffee.js @@ -1,11 +1,9 @@ var options = require('./options') +var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb) { - try { - var coffee = require('coffee-script') - } catch (err) { - return cb(err) - } + ensureRequire('coffee',['coffee-script']) + var coffee = require('coffee-script') try { var js = coffee.compile(raw, options.coffee || {}) } catch (err) { diff --git a/lib/compilers/jade.js b/lib/compilers/jade.js index 4a8393a..45980df 100644 --- a/lib/compilers/jade.js +++ b/lib/compilers/jade.js @@ -1,11 +1,9 @@ var options = require('./options') +var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb) { - try { - var jade = require('jade') - } catch (err) { - return cb(err) - } + ensureRequire('jade','jade') + var jade = require('jade') try { var html = jade.compile(raw, options.jade || {})() } catch (err) { diff --git a/lib/compilers/less.js b/lib/compilers/less.js index 4b17451..1b571c8 100644 --- a/lib/compilers/less.js +++ b/lib/compilers/less.js @@ -1,13 +1,11 @@ var options = require('./options') var assign = require('object-assign') var path = require('path') +var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb, compiler, filePath) { - try { - var less = require('less') - } catch (err) { - return cb(err) - } + ensureRequire('less','less') + var less = require('less') var opts = assign({ filename: path.basename(filePath) diff --git a/lib/compilers/pug.js b/lib/compilers/pug.js index a7e821c..4fd384f 100644 --- a/lib/compilers/pug.js +++ b/lib/compilers/pug.js @@ -1,11 +1,9 @@ var options = require('./options') +var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb) { - try { - var pug = require('pug') - } catch (err) { - return cb(err) - } + ensureRequire('pug','pug') + var pug = require('pug') try { var html = pug.compile(raw, options.pug || {})() } catch (err) { diff --git a/lib/compilers/sass.js b/lib/compilers/sass.js index 163ff68..20d696f 100644 --- a/lib/compilers/sass.js +++ b/lib/compilers/sass.js @@ -1,13 +1,11 @@ var options = require('./options') var assign = require('object-assign') var path = require('path') +var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb, compiler, filePath) { - try { - var sass = require('node-sass') - } catch (err) { - return cb(err) - } + ensureRequire('sass','node-sass') + var sass = require('node-sass') var sassOptions = assign({ data: raw, diff --git a/lib/compilers/stylus.js b/lib/compilers/stylus.js index e3c50ad..0f05720 100644 --- a/lib/compilers/stylus.js +++ b/lib/compilers/stylus.js @@ -1,13 +1,11 @@ var options = require('./options') var assign = require('object-assign') var path = require('path') +var ensureRequire = require('../ensure-require.js') module.exports = function (raw, cb, compiler, filePath) { - try { - var stylus = require('stylus') - } catch (err) { - return cb(err) - } + ensureRequire('stylus','stylus') + var stylus = require('stylus') var opts = assign({ filename: path.basename(filePath) diff --git a/lib/ensure-require.js b/lib/ensure-require.js new file mode 100644 index 0000000..ad4800c --- /dev/null +++ b/lib/ensure-require.js @@ -0,0 +1,32 @@ +module.exports = function(name,deps) { + var i,len,missing=[]; + if (typeof deps === "string") { + deps = [deps] + } + for (i = 0, len = deps.length; i < len; i++) { + var mis, req = deps[i] + if (typeof req === "string") { + mis = req + } else { + mis = req[1] + req = req[0] + } + try { + require.resolve(req) + } catch (e) { + missing.push(mis) + } + } + if (missing.length > 0) { + 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 ' + } else { + message += missing[0] + ' is ' + } + message += 'missing.\n\nTo install run:\n'+npmInstall + throw new Error(message) + } +} diff --git a/package.json b/package.json index 71262c9..5fe4aed 100644 --- a/package.json +++ b/package.json @@ -36,25 +36,18 @@ "through": "^2.3.6", "vue-template-validator": "^1.0.1" }, - "peerDependencies": { - "babel-core": "^6.8.0", - "babel-runtime": "^6.0.0", - "babel-preset-es2015": "^6.6.0", - "babel-plugin-transform-runtime": "^6.8.0", - "vue-hot-reload-api": "^1.2.0", - "vueify-insert-css": "^1.0.0" - }, "devDependencies": { "babel-core": "^6.8.0", - "babel-runtime": "^6.0.0", - "babel-preset-es2015": "^6.6.0", "babel-plugin-transform-runtime": "^6.6.1", + "babel-preset-es2015": "^6.6.0", + "babel-runtime": "^6.0.0", "coffee-script": "^1.10.0", "jade": "^1.11.0", "less": "^2.5.1", "mocha": "^2.3.3", "node-sass": "^3.3.3", "pug": "^2.0.0-alpha6", + "rewire": "^2.5.1", "stylus": "^0.52.4", "vue-hot-reload-api": "^1.2.0", "vueify-insert-css": "^1.0.0" diff --git a/test/test.js b/test/test.js index 202799a..f7b628e 100644 --- a/test/test.js +++ b/test/test.js @@ -72,4 +72,15 @@ describe('Vueify compiler', function () { .forEach(function (file) { test(path.basename(file, '.js')) }) + it('missing dependencies', function(done) { + var rewire = require('rewire') + var ensureRequire = rewire('../lib/ensure-require.js') + ensureRequire.__set__('require.resolve',function(){throw new Error()}) + compiler = rewire('../lib/compiler') + compiler.__set__('ensureRequire',ensureRequire) + compiler.compile('', function (err,result) { + assert.equal(err.message,'You are trying to use "styles". vueify-insert-css is missing.\n\nTo install run:\nnpm install --save-dev vueify-insert-css') + done() + }) + }) }) From af96700d16f3f1630b7972758a874b7743240979 Mon Sep 17 00:00:00 2001 From: unidwell Date: Fri, 27 May 2016 21:53:33 +0200 Subject: [PATCH 04/69] Added support for browserify transform options. (#89) --- README.md | 28 +++++++++++++++++++++++----- index.js | 6 ++++-- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 5c48cdd..a9ee01b 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Under the hood, the transform will: - extract the styles, compile them and insert them with the `insert-css` module. - extract the template, compile it and add it to your exported options. -You can `require()` other stuff in the `', function (err,result) { - assert.equal(err.message,'You are trying to use "styles". vueify-insert-css is missing.\n\nTo install run:\nnpm install --save-dev vueify-insert-css') - done() - }) - }) }) From 0633470f41bc88b98deb46b24a180c182e8ab925 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 29 May 2016 12:43:15 -0400 Subject: [PATCH 08/69] 8.5.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e3702a3..aa55ebc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "8.5.0", + "version": "8.5.1", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From 55ebb4925e8b9f2208378d608467455da06bf236 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 29 May 2016 12:47:27 -0400 Subject: [PATCH 09/69] fix tests --- test/expects/autoprefix.js | 2 +- test/expects/basic.js | 2 +- test/expects/less.js | 2 +- test/expects/multiple-styles.js | 2 +- test/expects/multiple.js | 2 +- test/expects/non-minified.js | 2 +- test/expects/sass.js | 2 +- test/expects/scoped.js | 2 +- test/expects/src.js | 2 +- test/expects/styl.js | 2 +- test/test.js | 1 + 11 files changed, 11 insertions(+), 10 deletions(-) diff --git a/test/expects/autoprefix.js b/test/expects/autoprefix.js index 89fc0f8..6cab46a 100644 --- a/test/expects/autoprefix.js +++ b/test/expects/autoprefix.js @@ -1,2 +1,2 @@ -var __vueify_insert__ = require("/Users/evan/Vue/vueify/lib/insert-css.js") +var __vueify_insert__ = require("{{insertCss}}") 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 index f5755e6..d7c5df1 100644 --- a/test/expects/basic.js +++ b/test/expects/basic.js @@ -1,4 +1,4 @@ -var __vueify_insert__ = require("/Users/evan/Vue/vueify/lib/insert-css.js") +var __vueify_insert__ = require("{{insertCss}}") var __vueify_style__ = __vueify_insert__.insert("html{font-size:20px}") "use strict"; diff --git a/test/expects/less.js b/test/expects/less.js index 50a50c4..f67cd5a 100644 --- a/test/expects/less.js +++ b/test/expects/less.js @@ -1,2 +1,2 @@ -var __vueify_insert__ = require("/Users/evan/Vue/vueify/lib/insert-css.js") +var __vueify_insert__ = require("{{insertCss}}") 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-styles.js b/test/expects/multiple-styles.js index 890401e..d84f057 100644 --- a/test/expects/multiple-styles.js +++ b/test/expects/multiple-styles.js @@ -1,2 +1,2 @@ -var __vueify_insert__ = require("/Users/evan/Vue/vueify/lib/insert-css.js") +var __vueify_insert__ = require("{{insertCss}}") 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 index 3387bc8..be601e3 100644 --- a/test/expects/multiple.js +++ b/test/expects/multiple.js @@ -1,4 +1,4 @@ -var __vueify_insert__ = require("/Users/evan/Vue/vueify/lib/insert-css.js") +var __vueify_insert__ = require("{{insertCss}}") 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() { diff --git a/test/expects/non-minified.js b/test/expects/non-minified.js index 787adb2..cf23941 100644 --- a/test/expects/non-minified.js +++ b/test/expects/non-minified.js @@ -1,3 +1,3 @@ -var __vueify_insert__ = require("/Users/evan/Vue/vueify/lib/insert-css.js") +var __vueify_insert__ = require("{{insertCss}}") 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/sass.js b/test/expects/sass.js index 2c000ea..da2561c 100644 --- a/test/expects/sass.js +++ b/test/expects/sass.js @@ -1,2 +1,2 @@ -var __vueify_insert__ = require("/Users/evan/Vue/vueify/lib/insert-css.js") +var __vueify_insert__ = require("{{insertCss}}") 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 index 07e99ac..707611a 100644 --- a/test/expects/scoped.js +++ b/test/expects/scoped.js @@ -1,3 +1,3 @@ -var __vueify_insert__ = require("/Users/evan/Vue/vueify/lib/insert-css.js") +var __vueify_insert__ = require("{{insertCss}}") 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 index 3954acd..50b4ecf 100644 --- a/test/expects/src.js +++ b/test/expects/src.js @@ -1,4 +1,4 @@ -var __vueify_insert__ = require("/Users/evan/Vue/vueify/lib/insert-css.js") +var __vueify_insert__ = require("{{insertCss}}") var __vueify_style__ = __vueify_insert__.insert("h1{font-size:12px}") 'use strict'; diff --git a/test/expects/styl.js b/test/expects/styl.js index 2c000ea..da2561c 100644 --- a/test/expects/styl.js +++ b/test/expects/styl.js @@ -1,2 +1,2 @@ -var __vueify_insert__ = require("/Users/evan/Vue/vueify/lib/insert-css.js") +var __vueify_insert__ = require("{{insertCss}}") var __vueify_style__ = __vueify_insert__.insert("body{font:100% Helvetica,sans-serif;color:#333}") diff --git a/test/test.js b/test/test.js index 202799a..ada7860 100644 --- a/test/test.js +++ b/test/test.js @@ -24,6 +24,7 @@ function test (name) { var fileContent = read(filePath) var expected = read('expects/' + name + '.js') .replace(/\{\{id\}\}/g, '_v-' + hash(require.resolve('./' + filePath))) + .replace(/\{\{insertCss\}\}/g, require.resolve('../lib/insert-css')) // test registering dependency var deps = [] From 933e492358c8f46d2740ff0ba61e0c70cd4e7a95 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 30 May 2016 18:01:26 -0400 Subject: [PATCH 10/69] avoid absolute paths in style code --- lib/compiler.js | 2 +- test/expects/autoprefix.js | 2 +- test/expects/basic.js | 2 +- test/expects/less.js | 2 +- test/expects/multiple-styles.js | 2 +- test/expects/multiple.js | 2 +- test/expects/non-minified.js | 2 +- test/expects/sass.js | 2 +- test/expects/scoped.js | 2 +- test/expects/src.js | 2 +- test/expects/styl.js | 2 +- test/test.js | 1 - 12 files changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index a872eca..636c960 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -112,7 +112,7 @@ compiler.compile = function (content, filePath, cb) { if (style) { style = JSON.stringify(style) output += - 'var __vueify_insert__ = require(' + JSON.stringify(require.resolve('./insert-css')) + ')\n' + + 'var __vueify_insert__ = require("vueify/lib/insert-css")\n' + 'var __vueify_style__ = __vueify_insert__.insert(' + style + ')\n' } // script diff --git a/test/expects/autoprefix.js b/test/expects/autoprefix.js index 6cab46a..4771cac 100644 --- a/test/expects/autoprefix.js +++ b/test/expects/autoprefix.js @@ -1,2 +1,2 @@ -var __vueify_insert__ = require("{{insertCss}}") +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 index d7c5df1..1a4337f 100644 --- a/test/expects/basic.js +++ b/test/expects/basic.js @@ -1,4 +1,4 @@ -var __vueify_insert__ = require("{{insertCss}}") +var __vueify_insert__ = require("vueify/lib/insert-css") var __vueify_style__ = __vueify_insert__.insert("html{font-size:20px}") "use strict"; diff --git a/test/expects/less.js b/test/expects/less.js index f67cd5a..ea9f0e0 100644 --- a/test/expects/less.js +++ b/test/expects/less.js @@ -1,2 +1,2 @@ -var __vueify_insert__ = require("{{insertCss}}") +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-styles.js b/test/expects/multiple-styles.js index d84f057..e02ef0c 100644 --- a/test/expects/multiple-styles.js +++ b/test/expects/multiple-styles.js @@ -1,2 +1,2 @@ -var __vueify_insert__ = require("{{insertCss}}") +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 index be601e3..a677dbc 100644 --- a/test/expects/multiple.js +++ b/test/expects/multiple.js @@ -1,4 +1,4 @@ -var __vueify_insert__ = require("{{insertCss}}") +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() { diff --git a/test/expects/non-minified.js b/test/expects/non-minified.js index cf23941..07c596c 100644 --- a/test/expects/non-minified.js +++ b/test/expects/non-minified.js @@ -1,3 +1,3 @@ -var __vueify_insert__ = require("{{insertCss}}") +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/sass.js b/test/expects/sass.js index da2561c..bdfc383 100644 --- a/test/expects/sass.js +++ b/test/expects/sass.js @@ -1,2 +1,2 @@ -var __vueify_insert__ = require("{{insertCss}}") +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 index 707611a..b79ecb7 100644 --- a/test/expects/scoped.js +++ b/test/expects/scoped.js @@ -1,3 +1,3 @@ -var __vueify_insert__ = require("{{insertCss}}") +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 index 50b4ecf..ad17b4a 100644 --- a/test/expects/src.js +++ b/test/expects/src.js @@ -1,4 +1,4 @@ -var __vueify_insert__ = require("{{insertCss}}") +var __vueify_insert__ = require("vueify/lib/insert-css") var __vueify_style__ = __vueify_insert__.insert("h1{font-size:12px}") 'use strict'; diff --git a/test/expects/styl.js b/test/expects/styl.js index da2561c..bdfc383 100644 --- a/test/expects/styl.js +++ b/test/expects/styl.js @@ -1,2 +1,2 @@ -var __vueify_insert__ = require("{{insertCss}}") +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/test.js b/test/test.js index ada7860..202799a 100644 --- a/test/test.js +++ b/test/test.js @@ -24,7 +24,6 @@ function test (name) { var fileContent = read(filePath) var expected = read('expects/' + name + '.js') .replace(/\{\{id\}\}/g, '_v-' + hash(require.resolve('./' + filePath))) - .replace(/\{\{insertCss\}\}/g, require.resolve('../lib/insert-css')) // test registering dependency var deps = [] From 01ad6a9a11780bae4ec88bbcd874d372b0aab8d3 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 30 May 2016 18:01:29 -0400 Subject: [PATCH 11/69] 8.5.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aa55ebc..5a55b55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "8.5.1", + "version": "8.5.2", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From b2bc45a79325d5932c9e2892aaf316d98d245aa6 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 30 May 2016 18:07:59 -0400 Subject: [PATCH 12/69] update readme [ci skip] --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 86deb88..6607e60 100644 --- a/README.md +++ b/README.md @@ -67,13 +67,14 @@ 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 do: +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\ - vueify-insert-css vue-hot-reload-api\ - babel-core babel-preset-es2015\ - babel-plugin-transform-runtime babel-runtime@5\ + babel-core\ + babel-preset-es2015\ + babel-runtime\ + babel-plugin-transform-runtime\ --save-dev ``` @@ -114,6 +115,12 @@ browserify('./main.js') .pipe(fs.createWriteStream("bundle.js")) ``` +## Building for Production + +Make sure to have the `NODE_ENV` environment variable set to `"production"` when building for production! This strips away unnecessary code (e.g. hot-reload) for smaller bundle size. + +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! From 17523abc4ac7f922f3145cd45a3455acf2bf0c3a Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 31 May 2016 19:17:48 -0400 Subject: [PATCH 13/69] avoid exposiing full paths in compiled code --- lib/compiler.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index 636c960..34268e3 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -136,10 +136,9 @@ compiler.compile = function (content, filePath, cb) { output += 'if (module.hot) {(function () {' + ' module.hot.accept()\n' + - ' var hotAPI = require(' + JSON.stringify(require.resolve('vue-hot-reload-api')) + ')\n' + + ' var hotAPI = require("vueify/node_modules/vue-hot-reload-api")\n' + ' hotAPI.install(require("vue"), true)\n' + ' if (!hotAPI.compatible) return\n' + - ' var id = ' + JSON.stringify(filePath) + '\n' + // remove style tag on dispose (style ? ' module.hot.dispose(function () {\n' + @@ -150,10 +149,10 @@ compiler.compile = function (content, filePath, cb) { ) + ' if (!module.hot.data) {\n' + // initial insert - ' hotAPI.createRecord(id, module.exports)\n' + + ' 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.update("' + id + '", module.exports, (typeof module.exports === "function" ? module.exports.options : module.exports).template)\n' + ' }\n' + '})()}' } From b26c438e7954d7c2b20a1e211e5bdb15518e0da1 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 31 May 2016 19:17:52 -0400 Subject: [PATCH 14/69] 8.5.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5a55b55..15002ea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "8.5.2", + "version": "8.5.3", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From 033c427a542d198bb6fa8d8688a763e6ef8eb864 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 1 Jun 2016 11:59:18 -0400 Subject: [PATCH 15/69] fix hot-reload-api path (fix #93) --- lib/compiler.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/compiler.js b/lib/compiler.js index 34268e3..09bb491 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -13,6 +13,15 @@ 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' +try { + require(hotReloadAPIPath) +} catch (e) { + // likely Npm 2.x + hotReloadAPIPath = 'vueify/node_modules/vue-hot-reload-api' +} + var htmlMinifyOptions = { collapseWhitespace: true, removeComments: true, @@ -136,7 +145,7 @@ compiler.compile = function (content, filePath, cb) { output += 'if (module.hot) {(function () {' + ' module.hot.accept()\n' + - ' var hotAPI = require("vueify/node_modules/vue-hot-reload-api")\n' + + ' var hotAPI = require("' + hotReloadAPIPath + '")\n' + ' hotAPI.install(require("vue"), true)\n' + ' if (!hotAPI.compatible) return\n' + // remove style tag on dispose From c86a25cd1677ca5640664e057f480c6ade185f83 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 1 Jun 2016 11:59:21 -0400 Subject: [PATCH 16/69] 8.5.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 15002ea..e11b99f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vueify", - "version": "8.5.3", + "version": "8.5.4", "description": "Vue component transform for Browserify", "main": "index.js", "repository": { From bce369d6e5e5802197288812a2435cf0a834e2ce Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Mon, 6 Jun 2016 23:01:00 +0900 Subject: [PATCH 17/69] Add License (#97) * add LICENSE file * add license section * update author --- LICENSE | 21 +++++++++++++++++++++ README.md | 4 ++++ 2 files changed, 25 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..231a94b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016 Evan You + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index 6607e60..da918e0 100644 --- a/README.md +++ b/README.md @@ -391,3 +391,7 @@ If you use Webpack, there's also [vue-loader](https://github.com/vuejs/vue-loade - 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`. + +## License + +[MIT](http://opensource.org/licenses/MIT) From aa0c205540497a9db1fa7bf36e2c06328d81a7a3 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 15 Jun 2016 15:25:31 -0400 Subject: [PATCH 18/69] 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 19/69] 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 20/69] 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 21/69] 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 22/69] 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 23/69] 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 24/69] 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 25/69] 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 26/69] 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 27/69] 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 28/69] 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 29/69] 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 30/69] 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 31/69] 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 32/69] 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 33/69] 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 34/69] 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 35/69] 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 36/69] 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 37/69] 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 43/69] 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 44/69] 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 45/69] 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 46/69] 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 47/69] 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 48/69] 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 49/69] 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 50/69] 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 51/69] 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 52/69] 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 53/69] 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 54/69] 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 55/69] 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 56/69] 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 57/69] 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 58/69] 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 59/69] 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 60/69] 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 61/69] 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 62/69] 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 63/69] 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 64/69] 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 65/69] 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 66/69] 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 67/69] 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 68/69] 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 69/69] 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. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy