diff --git a/.eslintrc.js b/.eslintrc.js index 69b6b5912..451755e07 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -8,7 +8,7 @@ module.exports = { browser: true, node: true }, - extends: 'standard', + extends: ['standard', 'standard-jsx'], // required to lint *.vue files plugins: [ 'html' diff --git a/examples/hello-world-jsx/pages/about.vue b/examples/hello-world-jsx/pages/about.vue deleted file mode 100644 index 26ed2649b..000000000 --- a/examples/hello-world-jsx/pages/about.vue +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/examples/hello-world-jsx/pages/index.js b/examples/hello-world-jsx/pages/index.js deleted file mode 100644 index 675e8981f..000000000 --- a/examples/hello-world-jsx/pages/index.js +++ /dev/null @@ -1,8 +0,0 @@ -export default { - render(h) { - return
-

Welcome !

- About page -
- } -} diff --git a/examples/jsx/README.md b/examples/jsx/README.md new file mode 100644 index 000000000..068b72b54 --- /dev/null +++ b/examples/jsx/README.md @@ -0,0 +1,5 @@ +# Render Functions & JSX Example + +## Documentation + +Vue: https://vuejs.org/v2/guide/render-function.html diff --git a/examples/jsx/components/test.vue b/examples/jsx/components/test.vue new file mode 100644 index 000000000..f7f9ca041 --- /dev/null +++ b/examples/jsx/components/test.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/examples/hello-world-jsx/package.json b/examples/jsx/package.json similarity index 83% rename from examples/hello-world-jsx/package.json rename to examples/jsx/package.json index abcca8b41..d6478c654 100644 --- a/examples/hello-world-jsx/package.json +++ b/examples/jsx/package.json @@ -1,5 +1,5 @@ { - "name": "hello-nuxt-jsx", + "name": "nuxt-jsx", "dependencies": { "nuxt": "latest" }, diff --git a/examples/jsx/pages/about.js b/examples/jsx/pages/about.js new file mode 100644 index 000000000..4bd675870 --- /dev/null +++ b/examples/jsx/pages/about.js @@ -0,0 +1,21 @@ + +import Test from '~/components/test.vue' + +export default { + head: { + title: 'About Page', + meta: [ + { hid: 'description', name: 'description', content: 'About page description' } + ] + }, + components: { + Test + }, + render() { + return
+

About page

+ +

Home page

+
+ } +} diff --git a/examples/jsx/pages/index.js b/examples/jsx/pages/index.js new file mode 100755 index 000000000..ab5d1cb93 --- /dev/null +++ b/examples/jsx/pages/index.js @@ -0,0 +1,20 @@ +export default { + head: { + title: 'Home page 🚀', + meta: [ + { hid: 'description', name: 'description', content: 'Home page description' } + ], + script: [ + { src: '/head.js' }, + // Supported since 1.0 + { src: '/body.js', body: true }, + { src: '/defer.js', defer: '' } + ] + }, + render() { + return
+

Home page 🚀

+ About page +
+ } +} diff --git a/lib/builder/builder.js b/lib/builder/builder.js index 61c39e367..1c4b41c13 100644 --- a/lib/builder/builder.js +++ b/lib/builder/builder.js @@ -251,10 +251,10 @@ export default class Builder { // -- Layouts -- if (fs.existsSync(resolve(this.options.srcDir, 'layouts'))) { - const layoutsFiles = await glob('layouts/**/*.vue', { cwd: this.options.srcDir }) + const layoutsFiles = await glob('layouts/**/*.{vue,js}', { cwd: this.options.srcDir }) let hasErrorLayout = false layoutsFiles.forEach((file) => { - let name = file.split('/').slice(1).join('/').replace(/\.vue$/, '') + let name = file.split('/').slice(1).join('/').replace(/\.(vue|js)$/, '') if (name === 'error') { hasErrorLayout = true return @@ -277,7 +277,7 @@ export default class Builder { // If user defined a custom method to create routes if (this._nuxtPages) { // Use nuxt.js createRoutes bases on pages/ - const files = await glob('pages/**/*.vue', { cwd: this.options.srcDir }) + const files = await glob('pages/**/*.{vue,js}', { cwd: this.options.srcDir }) templateVars.router.routes = createRoutes(files, this.options.srcDir) } else { templateVars.router.routes = this.options.build.createRoutes(this.options.srcDir) @@ -538,14 +538,14 @@ export default class Builder { r(src, 'layouts'), r(src, 'store'), r(src, 'middleware'), - r(src, 'layouts/*.vue'), - r(src, 'layouts/**/*.vue') + r(src, 'layouts/*.{vue,js}'), + r(src, 'layouts/**/*.{vue,js}') ] if (this._nuxtPages) { patterns.push( r(src, 'pages'), - r(src, 'pages/*.vue'), - r(src, 'pages/**/*.vue') + r(src, 'pages/*.{vue,js}'), + r(src, 'pages/**/*.{vue,js}') ) } const options = Object.assign({}, this.options.watchers.chokidar, { diff --git a/lib/common/utils.js b/lib/common/utils.js index bd49c0be6..b8fd3c604 100644 --- a/lib/common/utils.js +++ b/lib/common/utils.js @@ -212,13 +212,13 @@ export function cleanChildrenRoutes(routes, isChild = false) { export function createRoutes(files, srcDir) { let routes = [] files.forEach((file) => { - let keys = file.replace(/^pages/, '').replace(/\.vue$/, '').replace(/\/{2,}/g, '/').split('/').slice(1) + let keys = file.replace(/^pages/, '').replace(/\.(vue|js)$/, '').replace(/\/{2,}/g, '/').split('/').slice(1) let route = { name: '', path: '', component: r(srcDir, file) } let parent = routes keys.forEach((key, i) => { route.name = route.name ? route.name + '-' + key.replace('_', '') : key.replace('_', '') route.name += (key === '_') ? 'all' : '' - route.chunkName = file.replace(/\.vue$/, '') + route.chunkName = file.replace(/\.(vue|js)$/, '') let child = _.find(parent, { name: route.name }) if (child) { child.children = child.children || [] diff --git a/package.json b/package.json index ad6be4495..44cf11041 100644 --- a/package.json +++ b/package.json @@ -135,10 +135,12 @@ "cross-env": "^5.1.1", "eslint": "^4.12.1", "eslint-config-standard": "^10.2.1", + "eslint-config-standard-jsx": "^4.0.2", "eslint-plugin-html": "^4.0.1", "eslint-plugin-import": "^2.8.0", "eslint-plugin-node": "^5.2.1", "eslint-plugin-promise": "^3.6.0", + "eslint-plugin-react": "^7.5.1", "eslint-plugin-standard": "^3.0.1", "express": "^4.16.2", "finalhandler": "^1.1.0", diff --git a/test/basic.ssr.test.js b/test/basic.ssr.test.js index 3692ac4ed..a8abb5841 100755 --- a/test/basic.ssr.test.js +++ b/test/basic.ssr.test.js @@ -245,6 +245,11 @@ test('/router-guard', async t => { t.false(html.includes('Router Guard')) }) +test('/jsx', async t => { + const { html } = await nuxt.renderRoute('/jsx') + t.true(html.includes('

JSX Page

')) +}) + // Close server and ask nuxt to stop listening to file changes test.after('Closing server and nuxt.js', t => { nuxt.close() diff --git a/test/fixtures/basic/pages/jsx.js b/test/fixtures/basic/pages/jsx.js new file mode 100644 index 000000000..88923dce9 --- /dev/null +++ b/test/fixtures/basic/pages/jsx.js @@ -0,0 +1,7 @@ +export default { + render() { + return
+

JSX Page

+
+ } +} diff --git a/yarn.lock b/yarn.lock index 0cc7801d9..56f3fd244 100644 --- a/yarn.lock +++ b/yarn.lock @@ -308,6 +308,13 @@ array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -326,6 +333,10 @@ arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + asn1.js@^4.0.0: version "4.9.2" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.2.tgz#8117ef4f7ed87cd8f89044b5bff97ac243a16c9a" @@ -1809,6 +1820,10 @@ core-assert@^0.2.0: buf-compare "^1.0.0" is-error "^2.2.0" +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + core-js@^2.0.0, core-js@^2.4.0, core-js@^2.5.0: version "2.5.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" @@ -2192,7 +2207,7 @@ doctrine@1.5.0: esutils "^2.0.2" isarray "^1.0.0" -doctrine@^2.0.2: +doctrine@^2.0.0, doctrine@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075" dependencies: @@ -2374,6 +2389,24 @@ error-stack-parser@^2.0.0: dependencies: stackframe "^1.0.3" +es-abstract@^1.7.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: version "0.10.37" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.37.tgz#0ee741d148b80069ba27d020393756af257defc3" @@ -2468,6 +2501,10 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-config-standard-jsx@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz#009e53c4ddb1e9ee70b4650ffe63a7f39f8836e1" + eslint-config-standard@^10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz#c061e4d066f379dc17cd562c64e819b4dd454591" @@ -2520,6 +2557,15 @@ eslint-plugin-promise@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.6.0.tgz#54b7658c8f454813dc2a870aff8152ec4969ba75" +eslint-plugin-react@^7.5.1: + version "7.5.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz#52e56e8d80c810de158859ef07b880d2f56ee30b" + dependencies: + doctrine "^2.0.0" + has "^1.0.1" + jsx-ast-utils "^2.0.0" + prop-types "^15.6.0" + eslint-plugin-standard@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz#34d0c915b45edc6f010393c7eef3823b08565cf2" @@ -2785,6 +2831,18 @@ fastparse@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" +fbjs@^0.8.16: + version "0.8.16" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + fd-slicer@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" @@ -3015,7 +3073,7 @@ fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.0.2, function-bind@^1.1.0: +function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3574,12 +3632,20 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + is-ci@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" dependencies: ci-info "^1.0.0" +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + is-directory@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" @@ -3721,6 +3787,12 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + is-resolvable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" @@ -3741,6 +3813,10 @@ is-svg@^2.0.0: dependencies: html-comment-regex "^1.1.0" +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -3779,6 +3855,13 @@ isobject@^2.0.0: dependencies: isarray "1.0.0" +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -3946,6 +4029,12 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +jsx-ast-utils@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f" + dependencies: + array-includes "^3.0.3" + kind-of@^3.0.2: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -4119,7 +4208,7 @@ longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" -loose-envify@^1.0.0: +loose-envify@^1.0.0, loose-envify@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" dependencies: @@ -4417,6 +4506,13 @@ node-fetch@1.6.3: encoding "^0.1.11" is-stream "^1.0.1" +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + node-libs-browser@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" @@ -5532,6 +5628,20 @@ promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + dependencies: + asap "~2.0.3" + +prop-types@^15.6.0: + version "15.6.0" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.3.1" + object-assign "^4.1.1" + proxy-addr@~2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec" @@ -6186,7 +6296,7 @@ set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" -setimmediate@^1.0.4: +setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -6721,6 +6831,10 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" +ua-parser-js@^0.7.9: + version "0.7.17" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" + uglify-es@^3.2.0: version "3.2.1" resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.2.1.tgz#93de0aad8a1bb629c8a316f686351bc4d6ece687" @@ -7113,6 +7227,10 @@ whatwg-encoding@^1.0.1: dependencies: iconv-lite "0.4.19" +whatwg-fetch@>=0.10.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + whatwg-url@^6.3.0: version "6.4.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08"