├── packages ├── templates │ ├── env │ ├── rootfiles │ │ └── readme.md │ ├── readme.md │ ├── dotfiles │ │ ├── .commitlintrc.js │ │ ├── .eslintrc.js │ │ ├── .prettierrc.js │ │ ├── .eslintignore │ │ ├── .prettierignore │ │ └── .editorconfig │ ├── projects │ │ ├── basic │ │ │ ├── src │ │ │ │ └── pages │ │ │ │ │ └── index.vue │ │ │ └── nuxt.config.js │ │ └── fancy │ │ │ ├── src │ │ │ ├── components │ │ │ │ └── button │ │ │ │ │ ├── button.spec.js │ │ │ │ │ └── button.vue │ │ │ ├── styles │ │ │ │ ├── theme.scss │ │ │ │ └── index.scss │ │ │ ├── pages │ │ │ │ └── index.vue │ │ │ └── assets │ │ │ │ └── logo.svg │ │ │ └── nuxt.config.js │ ├── static │ │ └── icon.png │ ├── index.js │ ├── gitignore │ ├── vscode │ │ ├── jsconfig.json │ │ └── settings.json │ ├── package.json │ └── pkg.json ├── index │ ├── index.js │ ├── jest-preset.js │ ├── package.json │ └── readme.md ├── cli │ ├── readme.md │ ├── index.js │ ├── utils │ │ ├── index.js │ │ └── template.js │ ├── options │ │ ├── index.js │ │ ├── server.js │ │ └── common.js │ ├── commands │ │ ├── stats.js │ │ ├── lint.js │ │ ├── format.js │ │ ├── test.js │ │ ├── serve.js │ │ ├── clean.js │ │ └── init.js │ └── package.json ├── jest-preset │ ├── jest-preset.js │ ├── readme.md │ ├── babel.config.js │ ├── babel.transform.js │ ├── index.js │ └── package.json ├── utils │ ├── readme.md │ ├── package.json │ └── index.js ├── module │ ├── readme.md │ ├── templates │ │ ├── webfontloader.js │ │ ├── vue-tabbing.js │ │ ├── vue-static-data.js │ │ ├── vue-lazy-hydration.js │ │ ├── vue-pwa-installer.js │ │ ├── lazysizes.js │ │ └── vue-analytics.js │ ├── defaults.js │ ├── icon.js │ ├── eslint.js │ ├── plugins.js │ ├── package.json │ ├── utils.js │ └── index.js ├── eslint-config │ ├── readme.md │ ├── index.js │ └── package.json ├── prettier-config │ ├── readme.md │ ├── index.js │ └── package.json └── commitlint-config │ ├── readme.md │ ├── index.js │ └── package.json ├── .npmrc ├── .yarnrc ├── .eslintrc.js ├── .prettierrc.js ├── .commitlintrc.js ├── examples ├── benchmark │ ├── nuxt.config.js │ └── package.json ├── basic │ └── package.json └── fancy │ └── package.json ├── assets ├── icon.png ├── banner.png ├── assets.sketch └── logo.svg ├── docs ├── .vuepress │ ├── public │ │ ├── icon.png │ │ ├── banner.png │ │ ├── icons │ │ │ ├── 64x64.png │ │ │ ├── 120x120.png │ │ │ ├── 144x144.png │ │ │ ├── 152x152.png │ │ │ ├── 192x192.png │ │ │ ├── 384x384.png │ │ │ └── 512x512.png │ │ ├── manifest.json │ │ └── logo.svg │ └── config.js ├── package.json ├── commands │ ├── stats.md │ ├── clean.md │ ├── lint.md │ ├── serve.md │ ├── format.md │ ├── test.md │ ├── readme.md │ └── init.md ├── module │ ├── readme.md │ ├── plugins.md │ └── configuration.md ├── guide │ ├── dependencies.md │ ├── rationale.md │ ├── features.md │ └── readme.md └── readme.md ├── renovate.json ├── .eslintignore ├── .prettierignore ├── .editorconfig ├── lerna.json ├── .vscode └── settings.json ├── .gitignore ├── package.json ├── license ├── netlify.toml └── readme.md /packages/templates/env: -------------------------------------------------------------------------------- 1 | SECRET="shush" 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org 2 | -------------------------------------------------------------------------------- /packages/templates/rootfiles/readme.md: -------------------------------------------------------------------------------- 1 | # Nuxt Stack 2 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | registry "https://registry.npmjs.org" 2 | save-prefix "" 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./packages/eslint-config") 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./packages/prettier-config") 2 | -------------------------------------------------------------------------------- /packages/index/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require("nuxt-stack-module") 2 | -------------------------------------------------------------------------------- /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./packages/commitlint-config") 2 | -------------------------------------------------------------------------------- /packages/cli/readme.md: -------------------------------------------------------------------------------- 1 | # Nuxt Stack CLI 2 | 3 | https://nuxtstack.org 4 | -------------------------------------------------------------------------------- /packages/jest-preset/jest-preset.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./index") 2 | -------------------------------------------------------------------------------- /packages/utils/readme.md: -------------------------------------------------------------------------------- 1 | # Nuxt Stack Utils 2 | 3 | https://nuxtstack.org 4 | -------------------------------------------------------------------------------- /examples/benchmark/nuxt.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | srcDir: "src" 3 | } 4 | -------------------------------------------------------------------------------- /packages/module/readme.md: -------------------------------------------------------------------------------- 1 | # Nuxt Stack Module 2 | 3 | https://nuxtstack.org 4 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/assets/icon.png -------------------------------------------------------------------------------- /packages/cli/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | options: require("./options") 3 | } 4 | -------------------------------------------------------------------------------- /packages/index/jest-preset.js: -------------------------------------------------------------------------------- 1 | module.exports = require("jest-preset-nuxt-stack") 2 | -------------------------------------------------------------------------------- /packages/templates/readme.md: -------------------------------------------------------------------------------- 1 | # Nuxt Stack Templates 2 | 3 | https://nuxtstack.org 4 | -------------------------------------------------------------------------------- /assets/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/assets/banner.png -------------------------------------------------------------------------------- /packages/jest-preset/readme.md: -------------------------------------------------------------------------------- 1 | # Nuxt Stack Jest Preset 2 | 3 | https://nuxtstack.org 4 | -------------------------------------------------------------------------------- /assets/assets.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/assets/assets.sketch -------------------------------------------------------------------------------- /packages/cli/utils/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Template: require("./template") 3 | } 4 | -------------------------------------------------------------------------------- /packages/eslint-config/readme.md: -------------------------------------------------------------------------------- 1 | # Nuxt Stack ESLint Config 2 | 3 | https://nuxtstack.org 4 | -------------------------------------------------------------------------------- /packages/prettier-config/readme.md: -------------------------------------------------------------------------------- 1 | # Nuxt Stack Prettier Config 2 | 3 | https://nuxtstack.org 4 | -------------------------------------------------------------------------------- /packages/commitlint-config/readme.md: -------------------------------------------------------------------------------- 1 | # Nuxt Stack CommitLint Config 2 | 3 | https://nuxtstack.org 4 | -------------------------------------------------------------------------------- /packages/templates/dotfiles/.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["nuxt-stack"] 3 | } 4 | -------------------------------------------------------------------------------- /packages/templates/dotfiles/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["nuxt-stack"] 3 | } 4 | -------------------------------------------------------------------------------- /packages/templates/dotfiles/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require("prettier-config-nuxt-stack") 2 | -------------------------------------------------------------------------------- /packages/templates/projects/basic/src/pages/index.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /docs/.vuepress/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/docs/.vuepress/public/icon.png -------------------------------------------------------------------------------- /packages/commitlint-config/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@commitlint/config-conventional"] 3 | } 4 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:base", ":semanticCommitTypeAll(chore)"], 3 | "automerge": true 4 | } 5 | -------------------------------------------------------------------------------- /docs/.vuepress/public/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/docs/.vuepress/public/banner.png -------------------------------------------------------------------------------- /packages/cli/options/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | common: require("./common"), 3 | server: require("./server") 4 | } 5 | -------------------------------------------------------------------------------- /packages/templates/static/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/packages/templates/static/icon.png -------------------------------------------------------------------------------- /docs/.vuepress/public/icons/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/docs/.vuepress/public/icons/64x64.png -------------------------------------------------------------------------------- /docs/.vuepress/public/icons/120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/docs/.vuepress/public/icons/120x120.png -------------------------------------------------------------------------------- /docs/.vuepress/public/icons/144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/docs/.vuepress/public/icons/144x144.png -------------------------------------------------------------------------------- /docs/.vuepress/public/icons/152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/docs/.vuepress/public/icons/152x152.png -------------------------------------------------------------------------------- /docs/.vuepress/public/icons/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/docs/.vuepress/public/icons/192x192.png -------------------------------------------------------------------------------- /docs/.vuepress/public/icons/384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/docs/.vuepress/public/icons/384x384.png -------------------------------------------------------------------------------- /docs/.vuepress/public/icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagerfield/nuxt-stack/HEAD/docs/.vuepress/public/icons/512x512.png -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # folders 2 | node_modules 3 | templates 4 | coverage 5 | dist 6 | 7 | # dot 8 | .nuxt 9 | 10 | # files 11 | sw.js 12 | -------------------------------------------------------------------------------- /packages/prettier-config/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: "always", 3 | quoteProps: "consistent", 4 | jsxBracketSameLine: true, 5 | semi: false 6 | } 7 | -------------------------------------------------------------------------------- /packages/templates/dotfiles/.eslintignore: -------------------------------------------------------------------------------- 1 | # folders 2 | node_modules 3 | coverage 4 | build 5 | dist 6 | 7 | # hidden 8 | .nuxt 9 | 10 | # files 11 | sw.js 12 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "vuepress dev", 5 | "build": "vuepress build" 6 | }, 7 | "devDependencies": { 8 | "vuepress": "1.5.3" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/jest-preset/babel.config.js: -------------------------------------------------------------------------------- 1 | const options = { 2 | targets: { 3 | node: "current" 4 | } 5 | } 6 | 7 | module.exports = { 8 | presets: [["@babel/env", options], ["@nuxt/app", options]] 9 | } 10 | -------------------------------------------------------------------------------- /packages/templates/dotfiles/.prettierignore: -------------------------------------------------------------------------------- 1 | # folders 2 | node_modules 3 | coverage 4 | build 5 | dist 6 | 7 | # hidden 8 | .nuxt 9 | 10 | # files 11 | nuxt.config.js 12 | jsconfig.json 13 | package.json 14 | -------------------------------------------------------------------------------- /packages/templates/index.js: -------------------------------------------------------------------------------- 1 | const { join } = require("path") 2 | 3 | const templatesDir = __dirname 4 | 5 | module.exports = { 6 | resolveTemplate: (...args) => join(templatesDir, ...args), 7 | templatesDir 8 | } 9 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # folders 2 | node_modules 3 | templates 4 | coverage 5 | dist 6 | 7 | # dot 8 | .nuxt 9 | 10 | # files 11 | config.js 12 | nuxt.config.js 13 | jsconfig.json 14 | package.json 15 | lerna.json 16 | pkg.json 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 2 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /packages/module/templates/webfontloader.js: -------------------------------------------------------------------------------- 1 | import WebFont from "webfontloader" 2 | 3 | export default (context) => { 4 | let opts = <%= serialize(options) %> 5 | if (typeof opts === "function") opts = opts(context) 6 | 7 | WebFont.load(opts) 8 | } 9 | -------------------------------------------------------------------------------- /packages/jest-preset/babel.transform.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require("path") 2 | const { createTransformer } = require("babel-jest") 3 | 4 | module.exports = createTransformer({ 5 | configFile: resolve(__dirname, "babel.config.js"), 6 | babelrc: false 7 | }) 8 | -------------------------------------------------------------------------------- /packages/templates/dotfiles/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 2 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /packages/templates/gitignore: -------------------------------------------------------------------------------- 1 | # folders 2 | node_modules 3 | coverage 4 | build 5 | dist 6 | 7 | # hidden 8 | .nuxt 9 | .env 10 | 11 | # files 12 | sitemap.xml.gz 13 | sitemap.xml 14 | sw.js 15 | 16 | # logs 17 | *.log 18 | 19 | # system 20 | .DS_Store 21 | -------------------------------------------------------------------------------- /packages/templates/projects/fancy/src/components/button/button.spec.js: -------------------------------------------------------------------------------- 1 | import { mount } from "@vue/test-utils" 2 | import Button from "./button.vue" 3 | 4 | it("renders snapshot", () => { 5 | const wrapper = mount(Button) 6 | expect(wrapper).toMatchSnapshot() 7 | }) 8 | -------------------------------------------------------------------------------- /packages/module/templates/vue-tabbing.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue" 2 | import VueTabbing from "vue-tabbing" 3 | 4 | export default (context) => { 5 | let opts = <%= serialize(options) %> 6 | if (typeof opts === "function") opts = opts(context) 7 | 8 | Vue.use(VueTabbing, opts) 9 | } 10 | -------------------------------------------------------------------------------- /packages/module/templates/vue-static-data.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue" 2 | import VueStaticData from "vue-static-data" 3 | 4 | export default (context) => { 5 | let opts = <%= serialize(options) %> 6 | if (typeof opts === "function") opts = opts(context) 7 | 8 | Vue.use(VueStaticData, opts) 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/options/server.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | host: { 3 | alias: "H", 4 | type: "string", 5 | default: "0.0.0.0", 6 | description: "Server host" 7 | }, 8 | port: { 9 | alias: "p", 10 | type: "string", 11 | default: "5000", 12 | description: "Server port" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/templates/vscode/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["node_modules", "<%=generateDir%>", "<%=buildDir%>"], 3 | "compilerOptions": { 4 | "moduleResolution": "node", 5 | "baseUrl": ".", 6 | "paths": { 7 | "@/*": ["<%=dot(srcDir)%>/*"], 8 | "~/*": ["<%=dot(srcDir)%>/*"] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.8.1", 3 | "npmClient": "yarn", 4 | "useWorkspaces": true, 5 | "exact": true, 6 | "command": { 7 | "version": { 8 | "npmClient": "npm", 9 | "allowBranch": "master", 10 | "message": "chore(release): publish %v" 11 | } 12 | }, 13 | "packages": [ 14 | "examples/*", 15 | "packages/*" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/module/templates/vue-lazy-hydration.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue" 2 | import VueLazyHydration from "vue-lazy-hydration" 3 | 4 | export default (context) => { 5 | let opts = <%= serialize(options) %> 6 | if (typeof opts === "function") opts = opts(context) 7 | 8 | const pluginOptions = Object.assign({ name: "VHydrate" }, opts) 9 | 10 | Vue.component(pluginOptions.name, VueLazyHydration) 11 | } 12 | -------------------------------------------------------------------------------- /packages/templates/projects/fancy/src/styles/theme.scss: -------------------------------------------------------------------------------- 1 | $heading-font-fallback: "Arial", sans-serif; 2 | $heading-font-family: "Quicksand", $heading-font-fallback; 3 | 4 | $mono-font-fallback: "Monaco", monospace; 5 | $mono-font-family: "Roboto Mono", $mono-font-fallback; 6 | 7 | $white: #ffffff; 8 | $smoke: #f2f2f8; 9 | $black: #101020; 10 | 11 | $green-1: #00c58e; 12 | $green-2: #108775; 13 | $green-3: #2f495e; 14 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.codeActionsOnSave": { 4 | "source.fixAll": true 5 | }, 6 | "eslint.validate": ["javascript", "typescript", "vue"], 7 | "files.exclude": { 8 | "**/node_modules": false, 9 | "**/.nuxt": false 10 | }, 11 | "[javascript]": { 12 | "editor.formatOnSave": false 13 | }, 14 | "[vue]": { 15 | "editor.formatOnSave": false 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/templates/vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.codeActionsOnSave": { 4 | "source.fixAll": true 5 | }, 6 | "eslint.validate": ["javascript", "typescript", "vue"], 7 | "files.exclude": { 8 | "**/node_modules": true, 9 | "**/<%=buildDir%>": true 10 | }, 11 | "[javascript]": { 12 | "editor.formatOnSave": false 13 | }, 14 | "[vue]": { 15 | "editor.formatOnSave": false 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/module/templates/vue-pwa-installer.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue" 2 | import { createInstaller } from "vue-pwa-installer" 3 | 4 | export default (context, inject) => { 5 | let opts = <%= serialize(options) %> 6 | if (typeof opts === "function") opts = opts(context) 7 | 8 | const installer = createInstaller(Vue, opts) 9 | const prototypeKey = opts.prototypeKey || "$installer" 10 | 11 | inject(prototypeKey.replace(/^\$/, ""), installer) 12 | } 13 | -------------------------------------------------------------------------------- /packages/module/templates/lazysizes.js: -------------------------------------------------------------------------------- 1 | <%(options.plugins || [ 2 | "respimg", 3 | "optimumx", 4 | "object-fit", 5 | "parent-fit" 6 | ]).forEach((plugin) => {%> 7 | import "lazysizes/plugins/<%=plugin%>/ls.<%=plugin%>"<% }) %> 8 | import lazysizes from "lazysizes" 9 | 10 | export default (context) => { 11 | let opts = <%= serialize(options.options || {}) %> 12 | if (typeof opts === "function") opts = opts(context) 13 | 14 | Object.assign(lazysizes.cfg, opts) 15 | } 16 | -------------------------------------------------------------------------------- /packages/module/templates/vue-analytics.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue" 2 | import VueAnalytics from "vue-analytics" 3 | import merge from "deepmerge" 4 | 5 | export default (context) => { 6 | let opts = <%= serialize(options) %> 7 | if (typeof opts === "function") opts = opts(context) 8 | 9 | const debug = { sendHitTask: !context.isDev } 10 | const pluginOptions = merge({ debug }, opts) 11 | 12 | pluginOptions.router = context.app.router 13 | 14 | Vue.use(VueAnalytics, pluginOptions) 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # folders 2 | node_modules 3 | coverage 4 | build 5 | dist 6 | 7 | # dot 8 | .nuxt 9 | .env 10 | 11 | # files 12 | sitemap.xml.gz 13 | sitemap.xml 14 | todo.md 15 | sw.js 16 | 17 | # basic example 18 | examples/basic/* 19 | !examples/basic/package.json 20 | 21 | # benchmark example 22 | examples/benchmark/* 23 | !examples/benchmark/package.json 24 | !examples/benchmark/nuxt.config.js 25 | 26 | # fancy example 27 | examples/fancy/* 28 | !examples/fancy/package.json 29 | 30 | # logs 31 | *.log 32 | 33 | # system 34 | .DS_Store 35 | -------------------------------------------------------------------------------- /packages/templates/projects/basic/nuxt.config.js: -------------------------------------------------------------------------------- 1 | export default {<% 2 | if (cfg('srcDir')) { %> 3 | srcDir: "<%= cfg('srcDir') %>",<% } %><% 4 | if (cfg('buildDir')) { %> 5 | buildDir: "<%= cfg('buildDir') %>",<% } %><% 6 | if (cfg('generateDir')) { %> 7 | generate: { dir: "<%= cfg('generateDir') %>" },<% } %> 8 | modules: ["nuxt-stack"], 9 | stack: { 10 | name: "Nuxt Stack", 11 | host: "https://nuxtstack.org/", 12 | description: "Stacks of goodness for Nuxt", 13 | keywords: ["nuxt", "stack"] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/options/common.js: -------------------------------------------------------------------------------- 1 | const { defaultNuxtConfigFile } = require("@nuxt/config") 2 | 3 | module.exports = { 4 | "config-file": { 5 | alias: "c", 6 | type: "string", 7 | default: defaultNuxtConfigFile, 8 | description: `Path to Nuxt config file\nDefault: ${defaultNuxtConfigFile}` 9 | }, 10 | version: { 11 | alias: "v", 12 | type: "boolean", 13 | description: "Display Nuxt version" 14 | }, 15 | help: { 16 | alias: "h", 17 | type: "boolean", 18 | description: "Display this message" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/cli/commands/stats.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const spawn = require("cross-spawn") 4 | const { NuxtCommand } = require("@nuxt/cli") 5 | const { common, server } = require("../options") 6 | 7 | const args = ["build", "--analyze", "--spa", "--no-generate"] 8 | 9 | NuxtCommand.run({ 10 | name: "stats", 11 | description: "Show build stats with webpack analyser", 12 | usage: "stats ", 13 | options: { 14 | ...server, 15 | ...common 16 | }, 17 | run(cmd) { 18 | spawn("nuxt", args.concat(cmd._argv), { stdio: "inherit" }) 19 | } 20 | }) 21 | -------------------------------------------------------------------------------- /packages/module/defaults.js: -------------------------------------------------------------------------------- 1 | export default { 2 | eslint: { 3 | formatter: "codeframe", 4 | emitWarning: true, 5 | cache: true, 6 | fix: true 7 | }, 8 | icon: { 9 | iconFileName: "icon.png" 10 | }, 11 | sitemap: { 12 | gzip: true 13 | }, 14 | stack: { 15 | lang: "en", 16 | name: "Nuxt Stack", 17 | host: "https://nuxtstack.org/", 18 | description: "Stacks of goodness for Nuxt", 19 | keywords: ["nuxt", "stack"], 20 | backgroundColor: "#FFFFFF", 21 | themeColor: "#4FC08D", 22 | normalizeCSS: true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-stack-utils", 3 | "description": "Nuxt Stack utils", 4 | "version": "0.8.1", 5 | "license": "MIT", 6 | "author": "Matthew Wagerfield ", 7 | "homepage": "https://nuxtstack.org", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/wagerfield/nuxt-stack.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/wagerfield/nuxt-stack/issues" 14 | }, 15 | "scripts": { 16 | "test": "echo test $npm_package_name version $npm_package_version" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/templates/projects/fancy/src/components/button/button.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | 16 | 29 | -------------------------------------------------------------------------------- /packages/cli/commands/lint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const spawn = require("cross-spawn") 4 | const { NuxtCommand } = require("@nuxt/cli") 5 | const { setNuxtSrcDir } = require("nuxt-stack-utils") 6 | const { common } = require("../options") 7 | 8 | const ext = ["js", "jsx", "ts", "tsx", "vue"].join(",") 9 | 10 | NuxtCommand.run({ 11 | name: "lint", 12 | description: "Lint code with ESLint", 13 | usage: "lint ", 14 | options: { 15 | ...common 16 | }, 17 | async run(cmd) { 18 | setNuxtSrcDir(await cmd.getNuxtConfig()) 19 | const args = ["--ext", ext].concat(cmd._argv) 20 | spawn("eslint", args, { stdio: "inherit" }) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /packages/templates/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-stack-templates", 3 | "description": "Nuxt Stack templates", 4 | "version": "0.8.1", 5 | "license": "MIT", 6 | "author": "Matthew Wagerfield ", 7 | "homepage": "https://nuxtstack.org", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/wagerfield/nuxt-stack.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/wagerfield/nuxt-stack/issues" 14 | }, 15 | "scripts": { 16 | "test": "echo test $npm_package_name version $npm_package_version" 17 | }, 18 | "dependencies": { 19 | "husky": "4.2.5", 20 | "lint-staged": "10.2.11" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/module/icon.js: -------------------------------------------------------------------------------- 1 | import { resolve } from "path" 2 | import { copyFileSync, existsSync } from "fs" 3 | import { resolveTemplate } from "nuxt-stack-templates" 4 | import defaults from "./defaults" 5 | 6 | export default function copyIcon(nuxtOptions) { 7 | const iconOptions = Object.assign({}, defaults.icon, nuxtOptions.icon) 8 | 9 | const { iconFileName, iconSrc } = iconOptions 10 | const { dir, srcDir } = nuxtOptions 11 | 12 | const iconSrcPath = resolveTemplate("static/icon.png") 13 | const iconDestPath = iconSrc || resolve(srcDir, dir.static, iconFileName) 14 | const iconExists = existsSync(iconDestPath) 15 | 16 | if (!iconExists) copyFileSync(iconSrcPath, iconDestPath) 17 | } 18 | -------------------------------------------------------------------------------- /packages/module/eslint.js: -------------------------------------------------------------------------------- 1 | import defaults from "./defaults" 2 | import { isFunction, isNotFalse } from "./utils" 3 | 4 | export const eslintRule = (options) => ({ 5 | test: /\.(jsx?|tsx?|vue)$/, 6 | exclude: /node_modules/, 7 | enforce: "pre", 8 | use: [ 9 | { 10 | loader: "eslint-loader", 11 | options: Object.assign({}, defaults.eslint, options) 12 | } 13 | ] 14 | }) 15 | 16 | export default (options) => (config, context) => { 17 | if (context.isDev && context.isClient && isNotFalse(options)) { 18 | const eslintOptions = isFunction(options) ? options(context) : options 19 | const rule = eslintRule(eslintOptions) 20 | config.module.rules.push(rule) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/prettier-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prettier-config-nuxt-stack", 3 | "description": "Nuxt Stack Prettier config", 4 | "version": "0.8.1", 5 | "license": "MIT", 6 | "author": "Matthew Wagerfield ", 7 | "homepage": "https://nuxtstack.org", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/wagerfield/nuxt-stack.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/wagerfield/nuxt-stack/issues" 14 | }, 15 | "scripts": { 16 | "test": "echo test $npm_package_name version $npm_package_version" 17 | }, 18 | "dependencies": { 19 | "prettier": "2.0.5", 20 | "prettier-eslint-cli": "5.0.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/jest-preset/index.js: -------------------------------------------------------------------------------- 1 | const { join, resolve } = require("path") 2 | const { getNuxtSrcDir } = require("nuxt-stack-utils") 3 | 4 | const r = (path) => resolve(__dirname, path) 5 | 6 | module.exports = { 7 | globals: { 8 | "vue-jest": { 9 | babelConfig: r("babel.config.js") 10 | } 11 | }, 12 | moduleFileExtensions: ["js", "json", "jsx", "ts", "tsx", "vue"], 13 | moduleNameMapper: { 14 | "^[~@]/(.*)$": join("", getNuxtSrcDir(), "$1") 15 | }, 16 | snapshotSerializers: ["jest-serializer-vue"], 17 | transform: { 18 | "^.+\\.(vue)$": "vue-jest", 19 | "^.+\\.(jsx?)$": r("babel.transform.js"), 20 | "^.+\\.(css|less|sass|scss|styl|jpg|png|svg)$": "jest-transform-stub" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/templates/projects/fancy/src/styles/index.scss: -------------------------------------------------------------------------------- 1 | html { 2 | color: $black; 3 | background: $smoke; 4 | font-family: $mono-font-fallback; 5 | font-size: 16px; 6 | line-height: 1.5; 7 | &.wf-active { 8 | font-family: $mono-font-family; 9 | } 10 | } 11 | 12 | h1 { 13 | font-family: $heading-font-fallback; 14 | font-size: 4rem; 15 | font-weight: 500; 16 | line-height: 1; 17 | .wf-active & { 18 | font-family: $heading-font-family; 19 | } 20 | } 21 | 22 | .tabbing :focus { 23 | outline: 3px dashed $green-3; 24 | outline-offset: 6px; 25 | } 26 | 27 | .green-1 { 28 | color: $green-1; 29 | } 30 | 31 | .green-2 { 32 | color: $green-2; 33 | } 34 | 35 | .green-3 { 36 | color: $green-3; 37 | } 38 | -------------------------------------------------------------------------------- /packages/commitlint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commitlint-config-nuxt-stack", 3 | "description": "Nuxt Stack CommitLint config", 4 | "version": "0.8.1", 5 | "license": "MIT", 6 | "author": "Matthew Wagerfield ", 7 | "homepage": "https://nuxtstack.org", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/wagerfield/nuxt-stack.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/wagerfield/nuxt-stack/issues" 14 | }, 15 | "scripts": { 16 | "test": "echo test $npm_package_name version $npm_package_version" 17 | }, 18 | "dependencies": { 19 | "@commitlint/cli": "9.1.1", 20 | "@commitlint/config-conventional": "9.1.1", 21 | "@commitlint/prompt-cli": "9.1.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "commit": "commit", 5 | "release": "node -r dotenv/config && lerna publish", 6 | "test": "lerna run test --stream", 7 | "diff": "lerna diff", 8 | "lint": "eslint ." 9 | }, 10 | "husky": { 11 | "hooks": { 12 | "pre-commit": "lint-staged", 13 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 14 | } 15 | }, 16 | "lint-staged": { 17 | "**/*.{js,vue}": [ 18 | "prettier --write", 19 | "eslint --fix", 20 | "git add" 21 | ], 22 | "**/*.{json,md,scss}": [ 23 | "prettier --write", 24 | "git add" 25 | ] 26 | }, 27 | "devDependencies": { 28 | "lerna": "3.22.1" 29 | }, 30 | "workspaces": [ 31 | "examples/*", 32 | "packages/*" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /packages/index/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-stack", 3 | "description": "Stack of modules and commands for building performant applications with zero configuration", 4 | "version": "0.8.1", 5 | "license": "MIT", 6 | "author": "Matthew Wagerfield ", 7 | "homepage": "https://nuxtstack.org", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/wagerfield/nuxt-stack.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/wagerfield/nuxt-stack/issues" 14 | }, 15 | "scripts": { 16 | "test": "echo test $npm_package_name version $npm_package_version" 17 | }, 18 | "dependencies": { 19 | "nuxt-stack-cli": "0.8.1", 20 | "nuxt-stack-module": "0.8.1" 21 | }, 22 | "peerDependencies": { 23 | "nuxt": "2.14.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /docs/commands/stats.md: -------------------------------------------------------------------------------- 1 | # `nuxt stats` 2 | 3 | Proxy to `nuxt build` passing the `--analyze --spa --no-generate` flags. 4 | 5 | Generates a [Webpack Analyzer Report][fancy-stats] for the client bundles. 6 | 7 | Usage: `nuxt stats [options]` 8 | 9 | | Option | Default | Description | 10 | | :-------------- | :-------- | :--------------------- | 11 | | `-H, --host` | `0.0.0.0` | Server hostname | 12 | | `-p, --port` | `5000` | Server port number | 13 | | `-v, --version` | `N/A` | Display `nuxt` version | 14 | | `-h, --help` | `N/A` | Display `help` dialog | 15 | 16 | ### Recipes 17 | 18 | Generate a Webpack Analyzer Report for the client bundles: 19 | 20 | ```bash 21 | nuxt stats 22 | ``` 23 | 24 | [fancy-stats]: https://fancy-stats.nuxtstack.org/client.html 25 | -------------------------------------------------------------------------------- /packages/eslint-config/index.js: -------------------------------------------------------------------------------- 1 | const { isProd, getNuxtSrcDir } = require("nuxt-stack-utils") 2 | 3 | module.exports = { 4 | root: true, 5 | extends: [ 6 | "standard", 7 | "plugin:import/errors", 8 | "plugin:import/warnings", 9 | "plugin:jest/recommended", 10 | "plugin:vue/recommended", 11 | "@vue/prettier" 12 | ], 13 | parserOptions: { 14 | parser: "babel-eslint" 15 | }, 16 | env: { 17 | serviceworker: true, 18 | browser: true, 19 | node: true, 20 | jest: true 21 | }, 22 | globals: { 23 | workbox: false 24 | }, 25 | settings: { 26 | "import/resolver": { 27 | nuxt: { 28 | nuxtSrcDir: getNuxtSrcDir() 29 | } 30 | } 31 | }, 32 | rules: { 33 | "no-console": isProd() ? "error" : "off", 34 | "no-debugger": isProd() ? "error" : "off" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/utils/index.js: -------------------------------------------------------------------------------- 1 | const setNuxtSrcDir = (config) => { 2 | let srcDir = (config && config.srcDir) || "" 3 | srcDir = srcDir.replace(config.rootDir, "") 4 | srcDir = srcDir.replace(/^\//, "") 5 | srcDir = srcDir.replace(/\/$/, "") 6 | process.env.NUXT_SRC_DIR = srcDir 7 | } 8 | 9 | const getNuxtSrcDir = (config) => { 10 | let srcDir = config && config.srcDir 11 | if (!srcDir) srcDir = process.env.NUXT_SRC_DIR 12 | return typeof srcDir === "string" ? srcDir : "src" 13 | } 14 | 15 | const getNodeEnv = () => process.env.NODE_ENV 16 | 17 | const isTest = () => getNodeEnv() === "test" 18 | 19 | const isProd = () => getNodeEnv() === "production" 20 | 21 | const isDev = () => getNodeEnv() !== "production" 22 | 23 | module.exports = { 24 | setNuxtSrcDir, 25 | getNuxtSrcDir, 26 | getNodeEnv, 27 | isTest, 28 | isProd, 29 | isDev 30 | } 31 | -------------------------------------------------------------------------------- /packages/cli/commands/format.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const spawn = require("cross-spawn") 4 | const { without } = require("lodash") 5 | const { NuxtCommand } = require("@nuxt/cli") 6 | const { setNuxtSrcDir } = require("nuxt-stack-utils") 7 | const { common } = require("../options") 8 | 9 | NuxtCommand.run({ 10 | name: "format", 11 | description: "Format code with Prettier", 12 | usage: "format ", 13 | options: { 14 | lint: { 15 | alias: "l", 16 | type: "boolean", 17 | description: "Pass to prettier-eslint" 18 | }, 19 | ...common 20 | }, 21 | async run(cmd) { 22 | setNuxtSrcDir(await cmd.getNuxtConfig()) 23 | const command = cmd.argv.lint ? "prettier-eslint" : "prettier" 24 | const argv = without(cmd._argv, "--lint", "-l") 25 | const args = argv.length ? argv : ["--help"] 26 | spawn(command, args, { stdio: "inherit" }) 27 | } 28 | }) 29 | -------------------------------------------------------------------------------- /packages/cli/commands/test.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const spawn = require("cross-spawn") 4 | const { includes, without } = require("lodash") 5 | const { setNuxtSrcDir } = require("nuxt-stack-utils") 6 | const { NuxtCommand } = require("@nuxt/cli") 7 | const { common } = require("../options") 8 | 9 | const PRESET = "jest-preset-nuxt-stack" 10 | 11 | NuxtCommand.run({ 12 | name: "test", 13 | description: "Run tests with Jest", 14 | usage: "test ", 15 | options: { 16 | related: { 17 | alias: "r", 18 | type: "boolean", 19 | description: "Alias to --findRelatedTests" 20 | }, 21 | ...common 22 | }, 23 | async run(cmd) { 24 | setNuxtSrcDir(await cmd.getNuxtConfig()) 25 | const args = without(cmd._argv, "--related", "-r") 26 | if (cmd.argv.related) args.push("--findRelatedTests") 27 | if (!includes(args, "--preset")) args.push("--preset", PRESET) 28 | spawn("jest", args, { stdio: "inherit" }) 29 | } 30 | }) 31 | -------------------------------------------------------------------------------- /docs/commands/clean.md: -------------------------------------------------------------------------------- 1 | # `nuxt clean` 2 | 3 | Proxy to `rimraf` passing the `buildDir` and `generate.dir` directories inferred from the Nuxt config. This command also deletes the `coverage` directory at the root of the project if found. 4 | 5 | Usage: `nuxt clean [options]` 6 | 7 | | Option | Default | Description | 8 | | :-------------- | :------ | :----------------------------------------------- | 9 | | `-l, --lock` | `false` | Delete `package-lock.json` and `yarn.lock` files | 10 | | `-m, --modules` | `false` | Delete the `node_modules` directory | 11 | | `-v, --version` | `N/A` | Display `nuxt` version | 12 | | `-h, --help` | `N/A` | Display `help` dialog | 13 | 14 | ### Recipes 15 | 16 | Delete all generated files and folders: 17 | 18 | ```bash 19 | nuxt clean 20 | ``` 21 | 22 | Delete all generated files, folders and lock files: 23 | 24 | ```bash 25 | nuxt clean --lock 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/commands/lint.md: -------------------------------------------------------------------------------- 1 | # `nuxt lint` 2 | 3 | Proxy to `eslint` with `--ext` preconfigured to `js,jsx,ts,tsx,vue` 4 | 5 | Nuxt Stack's ESLint config extends from [standard][standard-config] with added support for Vue, Jest, Prettier and Nuxt path alias `import` resolution. Check out the source for Nuxt Stack's [ESLint config here][eslint-config]. 6 | 7 | Usage: `nuxt lint [options]` 8 | 9 | | Option | Default | Description | 10 | | :-------------- | :------ | :--------------------- | 11 | | `-v, --version` | `N/A` | Display `nuxt` version | 12 | | `-h, --help` | `N/A` | Display `help` dialog | 13 | 14 | ### Recipes 15 | 16 | Lint all code in the components directory: 17 | 18 | ```bash 19 | nuxt lint src/components 20 | ``` 21 | 22 | Lint and automatically fix all code: 23 | 24 | ```bash 25 | nuxt lint . --fix 26 | ``` 27 | 28 | [standard-config]: https://github.com/standard/standard 29 | [eslint-config]: https://github.com/wagerfield/nuxt-stack/tree/master/packages/eslint-config 30 | -------------------------------------------------------------------------------- /packages/templates/projects/fancy/nuxt.config.js: -------------------------------------------------------------------------------- 1 | export default {<% 2 | if (cfg('srcDir')) { %> 3 | srcDir: "<%= cfg('srcDir') %>",<% } %><% 4 | if (cfg('buildDir')) { %> 5 | buildDir: "<%= cfg('buildDir') %>",<% } %><% 6 | if (cfg('generateDir')) { %> 7 | generate: { 8 | dir: "<%= cfg('generateDir') %>" 9 | },<% } %> 10 | modules: ["nuxt-stack"], 11 | styles: ["styles/index.scss"], 12 | styleResources: { 13 | scss: ["styles/theme.scss"] 14 | }, 15 | stack: { 16 | name: "Nuxt Stack", 17 | host: "https://nuxtstack.org/", 18 | description: "Stacks of goodness for Nuxt", 19 | keywords: ["nuxt", "stack"], 20 | backgroundColor: "#FFFFFF", 21 | themeColor: "#4FC08D", 22 | preconnect: [ 23 | "https://fonts.gstatic.com", 24 | "https://fonts.googleapis.com" 25 | ] 26 | }, 27 | webfonts: { 28 | google: { 29 | families: [ 30 | "Quicksand:500", 31 | "Roboto Mono:400&display=swap" // https://git.io/fjjcJ 32 | ] 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /docs/commands/serve.md: -------------------------------------------------------------------------------- 1 | # `nuxt serve` 2 | 3 | Proxy to `serve` passing the `generate.dir` directory inferred from the Nuxt config. 4 | 5 | Usage: `nuxt serve [options]` 6 | 7 | | Option | Default | Description | 8 | | :-------------- | :-------- | :---------------------------- | 9 | | `-b, --banner` | `false` | Show the fancy `serve` banner | 10 | | `-H, --host` | `0.0.0.0` | Server hostname | 11 | | `-p, --port` | `5000` | Server port number | 12 | | `-v, --version` | `N/A` | Display `nuxt` version | 13 | | `-h, --help` | `N/A` | Display `help` dialog | 14 | 15 | ### Recipes 16 | 17 | Serve the generated static site directory: 18 | 19 | ```bash 20 | nuxt serve 21 | ``` 22 | 23 | Serve the generated static site directory and show the fancy banner: 24 | 25 | ```bash 26 | nuxt serve --banner 27 | ``` 28 | 29 | Serve the generated static site on localhost port 8000: 30 | 31 | ```bash 32 | nuxt serve --host localhost --port 8000 33 | ``` 34 | -------------------------------------------------------------------------------- /packages/module/plugins.js: -------------------------------------------------------------------------------- 1 | import { resolve } from "path" 2 | import { either, isFunction, isNotFalse, isPlainObject } from "./utils" 3 | 4 | const isPluginOptions = either(isFunction, isPlainObject) 5 | 6 | export default function addPlugins() { 7 | const addPlugin = (key, file, mode, check) => { 8 | if (check(this.options[key])) { 9 | this.addPlugin({ 10 | src: resolve(__dirname, `templates/${file}.js`), 11 | options: this.options[key] || {}, 12 | mode 13 | }) 14 | } 15 | } 16 | 17 | // Client Plugins 18 | addPlugin("webfonts", "webfontloader", "client", isPluginOptions) 19 | addPlugin("lazysizes", "lazysizes", "client", isNotFalse) 20 | addPlugin("ga", "vue-analytics", "client", isPluginOptions) 21 | 22 | // Universal Plugins 23 | addPlugin("staticData", "vue-static-data", "all", isNotFalse) 24 | addPlugin("hydration", "vue-lazy-hydration", "all", isNotFalse) 25 | addPlugin("installer", "vue-pwa-installer", "all", isNotFalse) 26 | addPlugin("tabbing", "vue-tabbing", "all", isNotFalse) 27 | } 28 | -------------------------------------------------------------------------------- /packages/templates/pkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "dev": "nuxt", 4 | "clean": "nuxt clean", 5 | "serve": "nuxt serve", 6 | "start": "nuxt start", 7 | "stats": "nuxt stats", 8 | "build": "nuxt build --modern=server", 9 | "generate": "nuxt generate --modern=client", 10 | "format": "nuxt format --write --lint '*.{md}' '<%=slash(srcDir)%>**/*.{js,json,scss,vue}'", 11 | "lint": "nuxt lint . --fix", 12 | "test": "nuxt test", 13 | "commit": "commit" 14 | }, 15 | "husky": { 16 | "hooks": { 17 | "pre-commit": "lint-staged", 18 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 19 | } 20 | }, 21 | "lint-staged": { 22 | "<%=slash(srcDir)%>**/*.{js,vue}": [ 23 | "nuxt format --write --lint", 24 | "nuxt lint --fix", 25 | "nuxt test --related", 26 | "git add" 27 | ], 28 | "<%=slash(srcDir)%>**/*.{html,json,scss}": [ 29 | "nuxt format --write", 30 | "git add" 31 | ], 32 | "*.{md}": [ 33 | "nuxt format --write", 34 | "git add" 35 | ] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/.vuepress/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Nuxt Stack", 3 | "short_name": "Nuxt Stack", 4 | "start_url": "/index.html?standalone=true", 5 | "background_color": "#ffffff", 6 | "theme_color": "#4fc08d", 7 | "display": "standalone", 8 | "icons": [ 9 | { 10 | "src": "/icons/64x64.png", 11 | "sizes": "64x64", 12 | "type": "image/png" 13 | }, 14 | { 15 | "src": "/icons/120x120.png", 16 | "sizes": "120x120", 17 | "type": "image/png" 18 | }, 19 | { 20 | "src": "/icons/144x144.png", 21 | "sizes": "144x144", 22 | "type": "image/png" 23 | }, 24 | { 25 | "src": "/icons/152x152.png", 26 | "sizes": "152x152", 27 | "type": "image/png" 28 | }, 29 | { 30 | "src": "/icons/192x192.png", 31 | "sizes": "192x192", 32 | "type": "image/png" 33 | }, 34 | { 35 | "src": "/icons/384x384.png", 36 | "sizes": "384x384", 37 | "type": "image/png" 38 | }, 39 | { 40 | "src": "/icons/512x512.png", 41 | "sizes": "512x512", 42 | "type": "image/png" 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /packages/jest-preset/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jest-preset-nuxt-stack", 3 | "description": "Nuxt Stack Jest preset", 4 | "version": "0.8.1", 5 | "license": "MIT", 6 | "author": "Matthew Wagerfield ", 7 | "homepage": "https://nuxtstack.org", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/wagerfield/nuxt-stack.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/wagerfield/nuxt-stack/issues" 14 | }, 15 | "scripts": { 16 | "test": "echo test $npm_package_name version $npm_package_version" 17 | }, 18 | "dependencies": { 19 | "@babel/core": "7.11.1", 20 | "@babel/preset-env": "7.11.0", 21 | "@nuxt/babel-preset-app": "2.14.1", 22 | "@vue/test-utils": "1.0.3", 23 | "babel-core": "7.0.0-bridge.0", 24 | "babel-jest": "26.2.2", 25 | "jest": "26.2.2", 26 | "jest-serializer-vue": "2.0.2", 27 | "jest-transform-stub": "2.0.0", 28 | "nuxt-stack-utils": "0.8.1", 29 | "vue": "2.6.11", 30 | "vue-jest": "3.0.6", 31 | "vue-server-renderer": "2.6.11", 32 | "vue-template-compiler": "2.6.11" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Matthew Wagerfield 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/cli/commands/serve.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const spawn = require("cross-spawn") 4 | const { resolve } = require("path") 5 | const { first, without } = require("lodash") 6 | const { NuxtCommand } = require("@nuxt/cli") 7 | const { common, server } = require("../options") 8 | 9 | NuxtCommand.run({ 10 | name: "serve", 11 | description: "Serve generated static site", 12 | usage: "serve ", 13 | options: { 14 | banner: { 15 | alias: "b", 16 | type: "boolean", 17 | description: "Display serve banner" 18 | }, 19 | ...server, 20 | ...common 21 | }, 22 | async run(cmd) { 23 | const config = await cmd.getNuxtConfig() 24 | const nuxt = await cmd.getNuxt(config) 25 | 26 | const argvDir = first(cmd.argv._) 27 | const nuxtDir = nuxt.options.generate.dir 28 | const siteDir = resolve(argvDir || nuxtDir) 29 | 30 | const omit = [argvDir, "-b", "--banner"] 31 | const argv = without(cmd._argv, ...omit) 32 | const args = [siteDir].concat(argv) 33 | 34 | process.env.NODE_ENV = cmd.argv.banner ? "development" : "production" 35 | 36 | spawn("serve", args, { stdio: "inherit" }) 37 | } 38 | }) 39 | -------------------------------------------------------------------------------- /packages/eslint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-nuxt-stack", 3 | "description": "Nuxt Stack ESLint config", 4 | "version": "0.8.1", 5 | "license": "MIT", 6 | "author": "Matthew Wagerfield ", 7 | "homepage": "https://nuxtstack.org", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/wagerfield/nuxt-stack.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/wagerfield/nuxt-stack/issues" 14 | }, 15 | "scripts": { 16 | "test": "echo test $npm_package_name version $npm_package_version" 17 | }, 18 | "dependencies": { 19 | "@vue/eslint-config-prettier": "6.0.0", 20 | "babel-eslint": "10.1.0", 21 | "eslint": "7.6.0", 22 | "eslint-config-standard": "14.1.1", 23 | "eslint-import-resolver-nuxt": "1.0.1", 24 | "eslint-plugin-import": "2.22.0", 25 | "eslint-plugin-jest": "23.20.0", 26 | "eslint-plugin-node": "11.1.0", 27 | "eslint-plugin-prettier": "3.1.4", 28 | "eslint-plugin-promise": "4.2.1", 29 | "eslint-plugin-standard": "4.0.1", 30 | "eslint-plugin-vue": "6.2.2", 31 | "nuxt-stack-utils": "0.8.1", 32 | "prettier": "2.0.5" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-stack-example-basic", 3 | "version": "0.8.1", 4 | "private": true, 5 | "dependencies": { 6 | "nuxt": "2.4.5", 7 | "nuxt-stack": "0.8.1" 8 | }, 9 | "scripts": { 10 | "dev": "nuxt", 11 | "clean": "nuxt clean", 12 | "serve": "nuxt serve", 13 | "start": "nuxt start", 14 | "stats": "nuxt stats", 15 | "build": "nuxt build --modern=server", 16 | "generate": "nuxt generate --modern=client", 17 | "format": "nuxt format --write --lint '*.{md}' 'src/**/*.{js,json,scss,vue}'", 18 | "lint": "nuxt lint . --fix", 19 | "test": "nuxt test", 20 | "commit": "commit" 21 | }, 22 | "husky": { 23 | "hooks": { 24 | "pre-commit": "lint-staged", 25 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 26 | } 27 | }, 28 | "lint-staged": { 29 | "src/**/*.{js,vue}": [ 30 | "nuxt format --write --lint", 31 | "nuxt lint --fix", 32 | "nuxt test --related", 33 | "git add" 34 | ], 35 | "src/**/*.{html,json,scss}": [ 36 | "nuxt format --write", 37 | "git add" 38 | ], 39 | "*.{md}": [ 40 | "nuxt format --write", 41 | "git add" 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /examples/fancy/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-stack-example-fancy", 3 | "version": "0.8.1", 4 | "private": true, 5 | "dependencies": { 6 | "nuxt": "2.4.5", 7 | "nuxt-stack": "0.8.1" 8 | }, 9 | "scripts": { 10 | "dev": "nuxt", 11 | "clean": "nuxt clean", 12 | "serve": "nuxt serve", 13 | "start": "nuxt start", 14 | "stats": "nuxt stats", 15 | "build": "nuxt build --modern=server", 16 | "generate": "nuxt generate --modern=client", 17 | "format": "nuxt format --write --lint '*.{md}' 'src/**/*.{js,json,scss,vue}'", 18 | "lint": "nuxt lint . --fix", 19 | "test": "nuxt test", 20 | "commit": "commit" 21 | }, 22 | "husky": { 23 | "hooks": { 24 | "pre-commit": "lint-staged", 25 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 26 | } 27 | }, 28 | "lint-staged": { 29 | "src/**/*.{js,vue}": [ 30 | "nuxt format --write --lint", 31 | "nuxt lint --fix", 32 | "nuxt test --related", 33 | "git add" 34 | ], 35 | "src/**/*.{html,json,scss}": [ 36 | "nuxt format --write", 37 | "git add" 38 | ], 39 | "*.{md}": [ 40 | "nuxt format --write", 41 | "git add" 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /examples/benchmark/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-stack-example-benchmark", 3 | "version": "0.8.1", 4 | "private": true, 5 | "dependencies": { 6 | "nuxt": "2.4.5", 7 | "nuxt-stack": "0.8.1" 8 | }, 9 | "scripts": { 10 | "dev": "nuxt", 11 | "clean": "nuxt clean", 12 | "serve": "nuxt serve", 13 | "start": "nuxt start", 14 | "stats": "nuxt stats", 15 | "build": "nuxt build --modern=server", 16 | "generate": "nuxt generate --modern=client", 17 | "format": "nuxt format --write --lint '*.{md}' 'src/**/*.{js,json,scss,vue}'", 18 | "lint": "nuxt lint . --fix", 19 | "test": "nuxt test", 20 | "commit": "commit" 21 | }, 22 | "husky": { 23 | "hooks": { 24 | "pre-commit": "lint-staged", 25 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 26 | } 27 | }, 28 | "lint-staged": { 29 | "src/**/*.{js,vue}": [ 30 | "nuxt format --write --lint", 31 | "nuxt lint --fix", 32 | "nuxt test --related", 33 | "git add" 34 | ], 35 | "src/**/*.{html,json,scss}": [ 36 | "nuxt format --write", 37 | "git add" 38 | ], 39 | "*.{md}": [ 40 | "nuxt format --write", 41 | "git add" 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/cli/commands/clean.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const spawn = require("cross-spawn") 4 | const { NuxtCommand } = require("@nuxt/cli") 5 | const { common } = require("../options") 6 | 7 | NuxtCommand.run({ 8 | name: "clean", 9 | description: "Delete generated files", 10 | usage: "clean ", 11 | options: { 12 | lock: { 13 | alias: "l", 14 | type: "boolean", 15 | description: "Delete lock files" 16 | }, 17 | modules: { 18 | alias: "m", 19 | type: "boolean", 20 | description: "Delete node_modules" 21 | }, 22 | ...common 23 | }, 24 | async run(cmd) { 25 | const config = await cmd.getNuxtConfig() 26 | const nuxt = await cmd.getNuxt(config) 27 | 28 | const rootPath = nuxt.options.rootDir + "/" 29 | const stripRoot = (path) => path.replace(rootPath, "") 30 | 31 | const buildDir = stripRoot(nuxt.options.buildDir) 32 | const generateDir = stripRoot(nuxt.options.generate.dir) 33 | 34 | const args = [buildDir, generateDir, "coverage"] 35 | 36 | if (cmd.argv.lock) args.push("package-lock.json", "yarn.lock") 37 | if (cmd.argv.modules) args.push("node_modules") 38 | 39 | spawn("rimraf", args, { stdio: "inherit" }) 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /docs/module/readme.md: -------------------------------------------------------------------------------- 1 | # Nuxt Stack Module 2 | 3 | ```js 4 | // nuxt.config.js 5 | export default { 6 | modules: ["nuxt-stack"] 7 | } 8 | ``` 9 | 10 | The `nuxt-stack` module does a number of things: 11 | 12 | 1. [Overrides](#nuxt-overrides) some of Nuxt's default options 13 | 2. Installs and configures a suite of [plugins](./plugins.html) 14 | 3. Integrates `eslint-loader` with Webpack 15 | 16 | ## Nuxt Overrides 17 | 18 | Nuxt Stack overrides the following default options: 19 | 20 | ```js 21 | // nuxt.config.js 22 | export default { 23 | hardSource: true, 24 | generate: { 25 | fallback: true, // 200.html -> 404.html 26 | subFolders: false // about/index.html -> about.html 27 | }, 28 | messages: { 29 | back_to_home: "Return to home page", 30 | error_404: "Page not found" 31 | }, 32 | router: { 33 | linkActiveClass: "link-active", 34 | linkExactActiveClass: "link-active-exact" 35 | }, 36 | server: { 37 | host: "0.0.0.0", // Access server across the network 38 | port: 5000 // Default port used by serve 39 | } 40 | } 41 | ``` 42 | 43 | Check out the [plugins](./plugins.html) that are installed and configured by Nuxt Stack. Or head over to the [configuration page](./configuration.html) for information on what options can be passed to these plugins. 44 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | base = "docs" 3 | command = "npm run build" 4 | publish = "docs/.vuepress/dist" 5 | 6 | [[redirects]] 7 | from = "https://nuxtstack.netlify.com/*" 8 | to = "https://nuxtstack.org/:splat" 9 | force = true 10 | 11 | # EXAMPLE: BENCHMARK 12 | 13 | [context.benchmark-example] 14 | base = "examples/benchmark" 15 | command = "nuxt init -p basic && npm run generate" 16 | publish = "examples/benchmark/dist" 17 | 18 | [context.benchmark-stats] 19 | base = "examples/benchmark" 20 | command = "nuxt init -p basic && npm run stats" 21 | publish = "examples/benchmark/.nuxt/stats" 22 | 23 | # EXAMPLE: BASIC 24 | 25 | [context.basic-example] 26 | base = "examples/basic" 27 | command = "nuxt init -p basic && npm run generate" 28 | publish = "examples/basic/dist" 29 | 30 | [context.basic-stats] 31 | base = "examples/basic" 32 | command = "nuxt init -p basic && npm run stats" 33 | publish = "examples/basic/.nuxt/stats" 34 | 35 | # EXAMPLE: FANCY 36 | 37 | [context.fancy-example] 38 | base = "examples/fancy" 39 | command = "nuxt init -p fancy && npm run generate" 40 | publish = "examples/fancy/dist" 41 | 42 | [context.fancy-stats] 43 | base = "examples/fancy" 44 | command = "nuxt init -p fancy && npm run stats" 45 | publish = "examples/fancy/.nuxt/stats" 46 | -------------------------------------------------------------------------------- /docs/commands/format.md: -------------------------------------------------------------------------------- 1 | # `nuxt format` 2 | 3 | Proxy to `prettier` or `prettier-eslint` when passing the `--lint` flag. 4 | 5 | Nuxt Stack's Prettier config only overrides two settings: 6 | 7 | - `arrowParens: "always"` 8 | - `semi: false` 9 | 10 | Check out the source for Nuxt Stack's [Prettier config here][prettier-config]. 11 | 12 | Usage: `nuxt format [options]` 13 | 14 | | Option | Default | Description | 15 | | :-------------- | :------ | :------------------------------------------------- | 16 | | `-l, --lint` | `false` | Use `prettier-eslint` binary instead of `prettier` | 17 | | `-v, --version` | `N/A` | Display `nuxt` version | 18 | | `-h, --help` | `N/A` | Display `help` dialog | 19 | 20 | ### Recipes 21 | 22 | Format all `.js` and `.vue` files: 23 | 24 | ```bash 25 | nuxt format **/*.{js,vue} 26 | ``` 27 | 28 | Format and overwrite all `.js` files in the components directory: 29 | 30 | ```bash 31 | nuxt format src/components/**/*.js --write 32 | ``` 33 | 34 | Format and lint all `.scss` and `.vue` files in the source directory: 35 | 36 | ```bash 37 | nuxt format src/**/*.{scss,vue} --lint 38 | ``` 39 | 40 | [prettier-config]: https://github.com/wagerfield/nuxt-stack/tree/master/packages/prettier-config 41 | -------------------------------------------------------------------------------- /packages/module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-stack-module", 3 | "description": "Nuxt Stack module", 4 | "version": "0.8.1", 5 | "license": "MIT", 6 | "author": "Matthew Wagerfield ", 7 | "homepage": "https://nuxtstack.org", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/wagerfield/nuxt-stack.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/wagerfield/nuxt-stack/issues" 14 | }, 15 | "scripts": { 16 | "test": "echo test $npm_package_name version $npm_package_version" 17 | }, 18 | "dependencies": { 19 | "@nuxt/config": "2.14.1", 20 | "@nuxtjs/axios": "5.12.1", 21 | "@nuxtjs/dotenv": "1.4.1", 22 | "@nuxtjs/pwa": "3.0.0-beta.20", 23 | "@nuxtjs/sitemap": "2.4.0", 24 | "@nuxtjs/style-resources": "1.0.0", 25 | "deepmerge": "4.2.2", 26 | "eslint": "7.6.0", 27 | "eslint-loader": "4.0.2", 28 | "lazysizes": "5.2.2", 29 | "node-sass": "4.14.1", 30 | "normalize.css": "8.0.1", 31 | "nuxt-stack-templates": "0.8.1", 32 | "nuxt-svg-loader": "1.2.0", 33 | "sass-loader": "9.0.3", 34 | "vue-analytics": "5.22.1", 35 | "vue-lazy-hydration": "1.0.0-beta.14", 36 | "vue-pwa-installer": "0.2.0", 37 | "vue-static-data": "0.4.0", 38 | "vue-tabbing": "0.1.0", 39 | "webfontloader": "1.6.28", 40 | "webpack": "4.44.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docs/commands/test.md: -------------------------------------------------------------------------------- 1 | # `nuxt test` 2 | 3 | Proxy to `jest` with `--preset` preconfigured to `jest-preset-nuxt-stack` 4 | 5 | Nuxt Stack's Jest preset takes care of setting up Jest to work with Vue Single File Components and Nuxt's path aliases. It also lists `@vue/test-utils` as a dependency so you can import and assert Vue SFCs from the get go. Check out the source for Nuxt Stack's [Jest preset here][jest-preset]. 6 | 7 | Usage: `nuxt test [options]` 8 | 9 | | Option | Default | Description | 10 | | :-------------- | :------ | :----------------------------------------- | 11 | | `-r, --related` | `false` | Alias for Jest's `--findRelatedTests` flag | 12 | | `-v, --version` | `N/A` | Display `nuxt` version | 13 | | `-h, --help` | `N/A` | Display `help` dialog | 14 | 15 | ### Recipes 16 | 17 | Run all tests in the components directory in watch mode: 18 | 19 | ```bash 20 | nuxt test src/components --watch 21 | ``` 22 | 23 | Run all related tests for a given globbing pattern. Useful when using `lint-staged` to only run tests related to the files being committed. Note that `lint-staged` will pass all the file paths to this command, so you can omit `` in this case: 24 | 25 | ```bash 26 | nuxt test --related 27 | ``` 28 | 29 | [jest-preset]: https://github.com/wagerfield/nuxt-stack/tree/master/packages/jest-preset 30 | -------------------------------------------------------------------------------- /packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-stack-cli", 3 | "description": "Nuxt Stack CLI", 4 | "version": "0.8.1", 5 | "license": "MIT", 6 | "author": "Matthew Wagerfield ", 7 | "homepage": "https://nuxtstack.org", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/wagerfield/nuxt-stack.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/wagerfield/nuxt-stack/issues" 14 | }, 15 | "scripts": { 16 | "test": "echo test $npm_package_name version $npm_package_version" 17 | }, 18 | "bin": { 19 | "nuxt-clean": "./commands/clean.js", 20 | "nuxt-format": "./commands/format.js", 21 | "nuxt-init": "./commands/init.js", 22 | "nuxt-lint": "./commands/lint.js", 23 | "nuxt-serve": "./commands/serve.js", 24 | "nuxt-stats": "./commands/stats.js", 25 | "nuxt-test": "./commands/test.js" 26 | }, 27 | "dependencies": { 28 | "commitlint-config-nuxt-stack": "0.8.1", 29 | "consola": "2.15.0", 30 | "cross-env": "7.0.2", 31 | "cross-spawn": "7.0.3", 32 | "eslint-config-nuxt-stack": "0.8.1", 33 | "fs-extra": "9.0.1", 34 | "jest-preset-nuxt-stack": "0.8.1", 35 | "lodash": "4.17.19", 36 | "nuxt": "2.14.1", 37 | "nuxt-stack-templates": "0.8.1", 38 | "nuxt-stack-utils": "0.8.1", 39 | "prettier-config-nuxt-stack": "0.8.1", 40 | "read-pkg": "5.2.0", 41 | "rimraf": "3.0.2", 42 | "serve": "11.3.2", 43 | "write-pkg": "4.0.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/commands/readme.md: -------------------------------------------------------------------------------- 1 | # Commands 2 | 3 | Nuxt `2.4.0` introduced a new feature allowing [custom commands][nuxt-commands] to be added to Nuxt's CLI. 4 | 5 | Alongside `nuxt build` and `nuxt generate`, you can now run `nuxt init` and `nuxt test` among others listed below: 6 | 7 | | Command | Description | 8 | | :----------------------------- | :-------------------------------------------------------------------------- | 9 | | [`nuxt init`](./init.html) | Generate a project template to get you started | 10 | | [`nuxt test`](./test.html) | Test code with Jest using presets for handling Vue components | 11 | | [`nuxt lint`](./lint.html) | Lint code with ESLint using a preset config for resolving Nuxt path aliases | 12 | | [`nuxt format`](./format.html) | Format code with Prettier and optionally ESLint by passing `--lint` | 13 | | [`nuxt clean`](./clean.html) | Delete generated files and directories | 14 | | [`nuxt serve`](./serve.html) | Serve a statically generated site created with `nuxt generate` | 15 | | [`nuxt stats`](./stats.html) | Generate a Webpack Bundle Analyzer report showing client bundle build stats | 16 | 17 | ::: tip 18 | To view the usage dialog for any command add `--help` or `-h` 19 | 20 | For example: `nuxt init -h` or `nuxt test --help` 21 | 22 | The same information can also be found on the respective command page by clicking the command in the table above or in the navigation sidebar. 23 | ::: 24 | 25 | [nuxt-commands]: https://nuxtjs.org/guide/modules#module-package-commands 26 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | _Supercharge Nuxt_ with a suite of modules and commands for building _performant_ applications with _zero configuration_. 4 | 5 | ## Documentation 6 | 7 | - [Overview](https://nuxtstack.org) 8 | - [Guide](https://nuxtstack.org/guide/) 9 | - [Commands](https://nuxtstack.org/commands/) 10 | - [Module](https://nuxtstack.org/module/) 11 | 12 | ## Features 13 | 14 | - Get [100/100 on Google Lighthouse][google-lighthouse-report] out of the box 15 | - Write tests for Vue components without having to configure Jest 16 | - Have ESLint and Prettier lint and format your code automatically 17 | - Ships with popular modules like `@nuxtjs/pwa` and `@nuxtjs/axios` 18 | - Only bundles plugins that you use—keeping JS payloads as small as possible 19 | - Preconfigured with `normalize.css`, `sass-loader` and `@nuxtjs/style-resources` 20 | - Suite of `nuxt` commands for linting, formatting, testing and analysing your application 21 | - Extensive [documentation](https://nuxtstack.org) with live examples 22 | 23 | ## Get started 24 | 25 | ```bash 26 | # Make a new directory 27 | mkdir example && cd example 28 | 29 | # Install dependencies 30 | yarn add nuxt nuxt-stack 31 | 32 | # Initialise a new project 33 | yarn nuxt init 34 | 35 | # Start the dev server 36 | yarn dev 37 | ``` 38 | 39 | Head over to the [docs](https://nuxtstack.org) to learn more. 40 | 41 | ## Author 42 | 43 | [Matthew Wagerfield](https://github.com/wagerfield) 44 | 45 | ## License 46 | 47 | [MIT](https://github.com/wagerfield/nuxt-stack/blob/master/license) 48 | 49 | [google-lighthouse-report]: https://lighthouse-dot-webdotdevsite.appspot.com/lh/html?url=https://fancy-example.nuxtstack.org 50 | -------------------------------------------------------------------------------- /packages/index/readme.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | _Supercharge Nuxt_ with a suite of modules and commands for building _performant_ applications with _zero configuration_. 4 | 5 | ## Documentation 6 | 7 | - [Overview](https://nuxtstack.org) 8 | - [Guide](https://nuxtstack.org/guide/) 9 | - [Commands](https://nuxtstack.org/commands/) 10 | - [Module](https://nuxtstack.org/module/) 11 | 12 | ## Features 13 | 14 | - Get [100/100 on Google Lighthouse][google-lighthouse-report] out of the box 15 | - Write tests for Vue components without having to configure Jest 16 | - Have ESLint and Prettier lint and format your code automatically 17 | - Ships with popular modules like `@nuxtjs/pwa` and `@nuxtjs/axios` 18 | - Only bundles plugins that you use—keeping JS payloads as small as possible 19 | - Preconfigured with `normalize.css`, `sass-loader` and `@nuxtjs/style-resources` 20 | - Suite of `nuxt` commands for linting, formatting, testing and analysing your application 21 | - Extensive [documentation](https://nuxtstack.org) with live examples 22 | 23 | ## Get started 24 | 25 | ```bash 26 | # Make a new directory 27 | mkdir example && cd example 28 | 29 | # Install dependencies 30 | yarn add nuxt nuxt-stack 31 | 32 | # Initialise a new project 33 | yarn nuxt init 34 | 35 | # Start the dev server 36 | yarn dev 37 | ``` 38 | 39 | Head over to the [docs](https://nuxtstack.org) to learn more. 40 | 41 | ## Author 42 | 43 | [Matthew Wagerfield](https://github.com/wagerfield) 44 | 45 | ## License 46 | 47 | [MIT](https://github.com/wagerfield/nuxt-stack/blob/master/license) 48 | 49 | [google-lighthouse-report]: https://lighthouse-dot-webdotdevsite.appspot.com/lh/html?url=https://fancy-example.nuxtstack.org 50 | -------------------------------------------------------------------------------- /docs/commands/init.md: -------------------------------------------------------------------------------- 1 | # `nuxt init` 2 | 3 | Generates a project template. Use the default `fancy` template to see more features in action. Alternatively, use the `basic` template to generate just the configuration files and an empty `index.vue` page. 4 | 5 | Usage: `nuxt init [options]` 6 | 7 | | Option | Default | Description | 8 | | :------------------- | :------ | :------------------------------------------------------ | 9 | | `-s, --src-dir` | `src` | Source directory | 10 | | `-g, --generate-dir` | `dist` | Generate directory | 11 | | `-b, --build-dir` | `.nuxt` | Build directory | 12 | | `-o, --overwrite` | `false` | Overwrite any existing template files or configs | 13 | | `-t, --template` | `fancy` | Project template to use. Options are `basic` or `fancy` | 14 | | `-e, --vscode` | `false` | Output VSCode `settings.json` and `jsconfig.json` | 15 | | `-k, --no-hooks` | `true` | Do not inject scripts and hooks into `package.json` | 16 | | `-v, --version` | `N/A` | Display `nuxt` version | 17 | | `-h, --help` | `N/A` | Display `help` dialog | 18 | 19 | ### Recipes 20 | 21 | Generate the `basic` project template: 22 | 23 | ```bash 24 | nuxt init --template basic 25 | ``` 26 | 27 | Generate the `fancy` project template with VSCode settings and jsconfig: 28 | 29 | ```bash 30 | nuxt init --vscode 31 | ``` 32 | 33 | Generate the `fancy` project with the source folders (pages, styles etc.) at the root of the project: 34 | 35 | ```bash 36 | nuxt init --src-dir 37 | ``` 38 | -------------------------------------------------------------------------------- /packages/templates/projects/fancy/src/pages/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 33 | 34 | 83 | -------------------------------------------------------------------------------- /docs/guide/dependencies.md: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | 3 | Nuxt Stack ships with _a lot_ of functionality. With this functionality comes _a lot_ of dependencies. 4 | 5 | It's useful to know which dependencies are included with Nuxt Stack so you don't add them alongside `nuxt-stack` in your `package.json`. 6 | 7 | Check out the lists below for a breakdown of all the dependencies included with the [module](#module-dependencies) and [CLI](#cli-dependencies). 8 | 9 | ## Module Dependencies 10 | 11 | - `@nuxtjs/axios` 12 | - `@nuxtjs/dotenv` 13 | - `@nuxtjs/pwa` 14 | - `@nuxtjs/sitemap` 15 | - `@nuxtjs/style-resources` 16 | - `nuxt-svg-loader` 17 | - `vue-analytics` 18 | - `vue-lazy-hydration` 19 | - `vue-pwa-installer` 20 | - `vue-static-data` 21 | - `vue-tabbing` 22 | - `lazysizes` 23 | - `webfontloader` 24 | - `normalize.css` 25 | - `node-sass` + `sass-loader` 26 | - `eslint` + `eslint-loader` 27 | 28 | ## CLI Dependencies 29 | 30 | ### Utility 31 | 32 | - `consola` 33 | - `cross-env` 34 | - `cross-spawn` 35 | - `fs-extra` 36 | - `husky` 37 | - `lint-staged` 38 | - `rimraf` 39 | - `serve` 40 | 41 | ### CommitLint 42 | 43 | - `@commitlint/cli` 44 | - `@commitlint/config-conventional` 45 | - `@commitlint/prompt-cli` 46 | 47 | ### ESLint 48 | 49 | - `@vue/eslint-config-prettier` 50 | - `babel-eslint` 51 | - `eslint` 52 | - `eslint-config-standard` 53 | - `eslint-import-resolver-nuxt` 54 | - `eslint-plugin-import` 55 | - `eslint-plugin-jest` 56 | - `eslint-plugin-node` 57 | - `eslint-plugin-promise` 58 | - `eslint-plugin-standard` 59 | - `eslint-plugin-vue` 60 | 61 | ### Jest 62 | 63 | - `@babel/core` 64 | - `@babel/preset-env` 65 | - `@nuxt/babel-preset-app` 66 | - `@vue/test-utils` 67 | - `babel-core` 68 | - `babel-jest` 69 | - `jest` 70 | - `jest-serializer-vue` 71 | - `jest-transform-stub` 72 | - `vue` 73 | - `vue-jest` 74 | - `vue-server-renderer` 75 | - `vue-template-compiler` 76 | 77 | ### Prettier 78 | 79 | - `prettier` 80 | - `prettier-eslint-cli` 81 | -------------------------------------------------------------------------------- /docs/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | serviceWorker: true, 3 | ga: "UA-135327752-1", 4 | title: "Nuxt Stack", 5 | description: [ 6 | "Supercharge Nuxt with a suite of modules and commands for", 7 | "building performant applications with zero configuration." 8 | ].join(" "), 9 | head: [ 10 | ["link", { rel: "icon", href: `/icons/64x64.png` }], 11 | ["link", { rel: "manifest", href: "/manifest.json" }], 12 | ["meta", { name: "theme-color", content: "#4fc08d" }], 13 | ["meta", { name: "apple-mobile-web-app-capable", content: "yes" }], 14 | ["meta", { name: "apple-mobile-web-app-status-bar-style", content: "black" }], 15 | ["link", { rel: "apple-touch-icon", href: `/icons/152x152.png` }], 16 | ["link", { rel: "mask-icon", href: "/logo.svg", color: "#ffffff" }], 17 | ["meta", { name: "msapplication-TileImage", content: "/icons/144x144.png" }], 18 | ["meta", { name: "msapplication-TileColor", content: "#ffffff" }] 19 | ], 20 | themeConfig: { 21 | repo: "wagerfield/nuxt-stack", 22 | docsDir: "docs", 23 | editLinks: true, 24 | editLinkText: "Edit this page on GitHub", 25 | lastUpdated: "Last updated", 26 | displayAllHeaders: true, 27 | sidebar: { 28 | "/guide/": [ 29 | "", 30 | "rationale", 31 | "features", 32 | "dependencies" 33 | ], 34 | "/commands/": [ 35 | "", 36 | "init", 37 | "test", 38 | "lint", 39 | "format", 40 | "clean", 41 | "serve", 42 | "stats" 43 | ], 44 | "/module/": [ 45 | "", 46 | "plugins", 47 | "configuration" 48 | ] 49 | }, 50 | nav: [ 51 | { 52 | text: "Guide", 53 | link: "/guide/" 54 | }, 55 | { 56 | text: "Commands", 57 | link: "/commands/" 58 | }, 59 | { 60 | text: "Module", 61 | link: "/module/" 62 | } 63 | ] 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/.vuepress/public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/templates/projects/fancy/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/module/utils.js: -------------------------------------------------------------------------------- 1 | export const eq = (a, b) => a === b 2 | 3 | export const not = (f) => (v) => !f(v) 4 | 5 | export const both = (f1, f2) => (v) => f1(v) && f2(v) 6 | 7 | export const either = (f1, f2) => (v) => f1(v) || f2(v) 8 | 9 | export const isType = (t) => (v) => eq(typeof v, t) 10 | 11 | export const isNil = (v) => v == null 12 | 13 | export const isNotNil = not(isNil) 14 | 15 | export const isFalse = (v) => v === false 16 | 17 | export const isNotFalse = not(isFalse) 18 | 19 | export const isArray = Array.isArray 20 | 21 | export const isNotArray = not(isArray) 22 | 23 | export const isString = isType("string") 24 | 25 | export const isFunction = isType("function") 26 | 27 | export const isObject = both(isNotNil, isType("object")) 28 | 29 | export const isPlainObject = both(isNotArray, isObject) 30 | 31 | export const isNotPlainObject = not(isPlainObject) 32 | 33 | export const isEmpty = (v) => v.length === 0 34 | 35 | export const isNotEmpty = both(isArray, not(isEmpty)) 36 | 37 | export const assoc = (key, val, obj) => (obj[key] = val) 38 | 39 | export const insert = (method) => (key, val, obj) => { 40 | if (isNotNil(val)) { 41 | if (isNotArray(obj[key])) obj[key] = [] 42 | if (isArray(val)) obj[key][method](...val) 43 | else obj[key][method](val) 44 | } 45 | } 46 | 47 | const transduce = (fn, value, force) => { 48 | return (acc, key, idx, arr) => { 49 | let def = acc.def[key] 50 | let opt = acc.opt[key] 51 | if (idx === arr.length - 1) { 52 | const call = force || eq(def, opt) 53 | if (call) fn(key, value, acc.opt) 54 | return call 55 | } else { 56 | if (isNotPlainObject(def)) def = {} 57 | if (isNotPlainObject(opt)) opt = acc.opt[key] = {} 58 | return { def, opt } 59 | } 60 | } 61 | } 62 | 63 | export const inject = (defaultConfig, options) => { 64 | return (fn, force) => (path, value, override) => { 65 | const paths = isString(path) ? path.split(".") : path 66 | const reducer = transduce(fn, value, force || override) 67 | const initial = { def: defaultConfig, opt: options } 68 | return paths.reduce(reducer, initial) 69 | } 70 | } 71 | 72 | export const preconnectLink = (href) => ({ 73 | crossorigin: true, 74 | rel: "preconnect", 75 | href 76 | }) 77 | -------------------------------------------------------------------------------- /packages/cli/utils/template.js: -------------------------------------------------------------------------------- 1 | const consola = require("consola") 2 | const config = require("prettier-config-nuxt-stack") 3 | const { resolveTemplate } = require("nuxt-stack-templates") 4 | const { basename, join, relative } = require("path") 5 | const { bindAll, get, template } = require("lodash") 6 | const { format, getFileInfo } = require("prettier") 7 | const { 8 | copySync, 9 | lstatSync, 10 | readFileSync, 11 | outputFileSync, 12 | pathExistsSync 13 | } = require("fs-extra") 14 | 15 | const DEFAULTS = { 16 | generateDir: "dist", 17 | buildDir: ".nuxt", 18 | srcDir: "" 19 | } 20 | 21 | class Template { 22 | constructor(options) { 23 | this.rootDir = get(options, "rootDir") 24 | this.srcDir = get(options, "srcDir", "") 25 | this.buildDir = get(options, "buildDir", ".nuxt") 26 | this.generateDir = get(options, "generateDir", "dist") 27 | 28 | // Options 29 | this.exclude = get(options, "exclude", [".DS_Store"]) 30 | this.configFile = get(options, "configFile", "nuxt.config.js") 31 | this.logPrefix = get(options, "logPrefix", "Generated:") 32 | this.overwrite = get(options, "overwrite", false) 33 | 34 | // Bind 35 | bindAll(this, ["filter", "copy", "compile", "output", "write"]) 36 | bindAll(this, ["log", "cfg", "tpl", "dst", "src", "dot", "slash"]) 37 | } 38 | 39 | filter(src, dst) { 40 | const include = !this.exclude.includes(basename(src)) 41 | if (include && lstatSync(src).isFile()) { 42 | if (this.overwrite || !pathExistsSync(dst)) this.log(dst) 43 | } 44 | return include 45 | } 46 | 47 | copy(src, dst) { 48 | copySync(src, dst, { 49 | overwrite: this.overwrite, 50 | filter: this.filter 51 | }) 52 | } 53 | 54 | compile(src, fmt) { 55 | const info = getFileInfo.sync(src) 56 | const ignore = info.ignored || fmt === false 57 | const content = template(readFileSync(src, "utf8"))(this) 58 | const options = { parser: info.inferredParser, ...config } 59 | return ignore ? content : format(content, options) 60 | } 61 | 62 | output(str, dst) { 63 | if (this.overwrite || !pathExistsSync(dst)) { 64 | outputFileSync(dst, str) 65 | this.log(dst) 66 | } 67 | } 68 | 69 | write(src, dst, fmt) { 70 | this.output(this.compile(src, fmt), dst) 71 | } 72 | 73 | log(dst, prefix) { 74 | consola.info(prefix || this.logPrefix, relative(this.rootDir, dst)) 75 | } 76 | 77 | cfg(key) { 78 | return this[key] !== DEFAULTS[key] && this[key] 79 | } 80 | 81 | tpl(...args) { 82 | return resolveTemplate(...args) 83 | } 84 | 85 | dst(...args) { 86 | return join(this.rootDir, ...args) 87 | } 88 | 89 | src(...args) { 90 | return join(this.rootDir, this.srcDir, ...args) 91 | } 92 | 93 | dot(path) { 94 | return path || "." 95 | } 96 | 97 | slash(path) { 98 | return path && `${path}/` 99 | } 100 | } 101 | 102 | module.exports = Template 103 | -------------------------------------------------------------------------------- /docs/module/plugins.md: -------------------------------------------------------------------------------- 1 | # Plugins 2 | 3 | Below is a quick reference table of the modules and plugins that Nuxt Stack installs and configures: 4 | 5 | | Module | Description | 6 | | :------------------------------------------------ | :---------------------------------------------------------- | 7 | | [`@nuxtjs/axios`][nuxt-axios] | `axios` integration for making promise based HTTP requests | 8 | | [`@nuxtjs/dotenv`][nuxt-dotenv] | Loads `.env` and merges contents with Nuxt's `env` object | 9 | | [`@nuxtjs/pwa`][nuxt-pwa] | Collection of modules for developing PWAs | 10 | | [`@nuxtjs/sitemap`][nuxt-sitemap] | Automatically generate or serve a dynamic sitemap | 11 | | [`@nuxtjs/style-resources`][nuxt-style-resources] | Share variables and mixins across style files and SFCs | 12 | | [`nuxt-svg-loader`][nuxt-svg-loader] | Import SVGs as Vue components | 13 | | [`webfontloader`][webfontloader] | Load custom webfonts from services like Google and Typekit | 14 | | [`vue-analytics`][vue-analytics] | Google Analytics integration for Nuxt | 15 | | [`lazysizes`][lazysizes] | Lazily load images and videos when they become visible | 16 | | [`vue-pwa-installer`][vue-pwa-installer] | Simple interface for installing a PWA to the home screen | 17 | | [`vue-lazy-hydration`][vue-lazy-hydration] | Lazily hydrate Vue components using a variety of strategies | 18 | | [`vue-tabbing`][vue-tabbing] | Reactive flag triggered by tabbed keyboard navigation | 19 | | [`vue-static-data`][vue-static-data] | Declare static (non-reactive) data within Vue components | 20 | 21 | ::: tip NOTE 22 | Some plugins are only installed if module options are specified in the Nuxt config. 23 | 24 | For example `@nuxtjs/axios`, `webfontloader` and `vue-analytics` are only installed if module options are not `undefined`. This keeps the client bundles as small as possible. 25 | 26 | Other plugins like `vue-pwa-installer`, `lazysizes` etc. can be disabled by passing `false` to their module options. 27 | ::: 28 | 29 | Check out the [configuration page](./configuration.html) for information on what options can be passed to these plugins. 30 | 31 | [nuxt-axios]: https://axios.nuxtjs.org 32 | [nuxt-dotenv]: https://www.npmjs.com/package/@nuxtjs/dotenv 33 | [nuxt-pwa]: https://pwa.nuxtjs.org 34 | [nuxt-sitemap]: https://www.npmjs.com/package/@nuxtjs/sitemap 35 | [nuxt-style-resources]: https://www.npmjs.com/package/@nuxtjs/style-resources 36 | [nuxt-svg-loader]: https://www.npmjs.com/package/nuxt-svg-loader 37 | [webfontloader]: https://www.npmjs.com/package/webfontloader 38 | [vue-analytics]: https://www.npmjs.com/package/vue-analytics 39 | [lazysizes]: https://www.npmjs.com/package/lazysizes 40 | [vue-pwa-installer]: https://www.npmjs.com/package/vue-pwa-installer 41 | [vue-lazy-hydration]: https://www.npmjs.com/package/vue-lazy-hydration 42 | [vue-tabbing]: https://www.npmjs.com/package/vue-tabbing 43 | [vue-static-data]: https://www.npmjs.com/package/vue-static-data 44 | -------------------------------------------------------------------------------- /docs/readme.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroImage: /banner.png 4 | heroText: " " 5 | actionText: Get started → 6 | actionLink: /guide/ 7 | features: 8 | - title: "Measurably fast" 9 | details: "Want to get 100/100 on Google Lighthouse? Thought you might. Nuxt Stack lays the foundation needed to build a Performant Web App." 10 | - title: "PWA out of the box" 11 | details: "Streamlines the process of creating an installable, performant Progressive Web App using a suite of battle-tested tools, modules and techniques." 12 | - title: "Write tests, right away" 13 | details: "Nuxt Stack takes care of configuring Jest and Babel to work with Vue and Nuxt out of the box—freeing you to focus on writing tests not tooling." 14 | - title: "Zero configuration" 15 | details: "Install one module, run one command and you're away. Develop a production ready app in a fraction of the time." 16 | - title: "Command all the things" 17 | details: "Initialise, lint, format, test, analyse and serve a static app with a suite of new commands added to Nuxt's CLI." 18 | - title: "Make code great again" 19 | details: "Have ESLint and Prettier automatically keep your code in check so you can focus on some real problems." 20 | footer: MIT Licensed | Copyright 2019 Matthew Wagerfield 21 | --- 22 | 23 | ### Dive right in :sunglasses: 24 | 25 | ```bash 26 | # Make a new directory 27 | mkdir example && cd example 28 | 29 | # Install dependencies 30 | yarn add nuxt nuxt-stack 31 | 32 | # Initialise a new project 33 | yarn nuxt init 34 | 35 | # Start the dev server 36 | yarn dev 37 | ``` 38 | 39 | ### What just happened? I didn't know there was a `nuxt init` command? :thinking: 40 | 41 | You're right. There isn't normally. 42 | 43 | Nuxt Stack adds a number of commands alongside the ones you're familiar with. `nuxt init` is just one of them. 44 | 45 | Check out the [commands](/commands/) section to see what else Nuxt Stack can do. 46 | 47 | ### What's so special about Nuxt Stack? :innocent: 48 | 49 | Out of the box, the [default project template][fancy-example] will get [100/100 in a Google Lighthouse audit][google-lighthouse-report] _across the board_. 50 | 51 | If that's piqued your interest, check out some of the other [features](/guide/features.html) Nuxt Stack has to offer. 52 | 53 | ### How much bloat does Nuxt Stack add? :sweat_smile: 54 | 55 | Very little. It also depends on which plugins _you decide_ to use. 56 | 57 | Nuxt Stack is simply a collection of plugins and presets focused on delivering the best performance possible. 58 | 59 | Out of the box, the default project template will add [~15kb of JavaScript (gzipped)][fancy-stats] to a [bare bones Nuxt app][benchmark-stats]. This mainly comes from `lazysizes` **~7kb** and `webfontloader` **~5kb**. 60 | 61 | If you don't want to lazy load images or use custom webfonts you can disable these plugins and shed the extra weight. Some plugins like `axios`, `webfontloader` and `vue-analytics` are only included when configuration options are present in the Nuxt config. For example, the [basic project template][basic-example] doesn't use any custom webfonts so `webfontloader` isn't included in the [vendor bundle][basic-stats]. 62 | 63 | All plugins that Nuxt Stack provides are fully configurable, so you can _opt-in_ or _out_ as necessary. 64 | 65 | Check out the [configuration](/module/configuration.html) docs to learn more. 66 | 67 | [google-lighthouse-report]: https://lighthouse-dot-webdotdevsite.appspot.com/lh/html?url=https://fancy-example.nuxtstack.org 68 | [benchmark-stats]: https://benchmark-stats.nuxtstack.org/client.html 69 | [basic-example]: https://basic-example.nuxtstack.org 70 | [basic-stats]: https://basic-stats.nuxtstack.org/client.html 71 | [fancy-example]: https://fancy-example.nuxtstack.org 72 | [fancy-stats]: https://fancy-stats.nuxtstack.org/client.html 73 | -------------------------------------------------------------------------------- /packages/cli/commands/init.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const readPkg = require("read-pkg") 4 | const writePkg = require("write-pkg") 5 | const { join } = require("path") 6 | const { get, merge } = require("lodash") 7 | const { existsSync } = require("fs-extra") 8 | const { NuxtCommand } = require("@nuxt/cli") 9 | const { Template } = require("../utils") 10 | const { common } = require("../options") 11 | 12 | NuxtCommand.run({ 13 | name: "init", 14 | description: "Create starter files", 15 | usage: "init ", 16 | options: { 17 | "src-dir": { 18 | alias: "s", 19 | type: "string", 20 | default: "src", 21 | description: "Source directory\nDefault: src" 22 | }, 23 | "build-dir": { 24 | alias: "b", 25 | type: "string", 26 | default: ".nuxt", 27 | description: "Build directory\nDefault: .nuxt" 28 | }, 29 | "generate-dir": { 30 | alias: "g", 31 | type: "string", 32 | default: "dist", 33 | description: "Generate directory\nDefault: dist" 34 | }, 35 | "template": { 36 | alias: "t", 37 | type: "string", 38 | default: "fancy", 39 | description: [ 40 | "Project template to use", 41 | "Options: basic or fancy", 42 | "Default: fancy" 43 | ].join("\n") 44 | }, 45 | "overwrite": { 46 | alias: "o", 47 | type: "boolean", 48 | description: "Overwrite any existing template files" 49 | }, 50 | "vscode": { 51 | alias: "e", 52 | type: "boolean", 53 | description: "Output VSCode settings and jsconfig\nDefault: false" 54 | }, 55 | "hooks": { 56 | alias: "k", 57 | type: "boolean", 58 | default: true, 59 | description: "Inject scripts and hooks into package.json\nDefault: false" 60 | }, 61 | ...common 62 | }, 63 | async run(cmd) { 64 | const config = await cmd.getNuxtConfig() 65 | const api = new Template({ 66 | rootDir: get(config, "rootDir"), 67 | srcDir: get(config, "srcDir", cmd.argv["src-dir"]), 68 | buildDir: get(config, "buildDir", cmd.argv["build-dir"]), 69 | generateDir: get(config, "generate.dir", cmd.argv["generate-dir"]), 70 | configFile: get(cmd, "argv.config-file"), 71 | overwrite: get(cmd, "argv.overwrite") 72 | }) 73 | 74 | // Nuxt Config 75 | if (!api.configFile.endsWith(".js")) api.configFile += ".js" 76 | 77 | // Dot Files 78 | api.copy(api.tpl("dotfiles"), api.dst()) 79 | api.write(api.tpl("gitignore"), api.dst(".gitignore")) 80 | api.write(api.tpl("env"), api.dst(".env")) 81 | 82 | // VSCode Files 83 | if (cmd.argv.vscode) { 84 | const tplSettings = api.tpl("vscode/settings.json") 85 | const tplJSConfig = api.tpl("vscode/jsconfig.json") 86 | api.write(tplSettings, api.dst(".vscode/settings.json")) 87 | api.write(tplJSConfig, api.dst("jsconfig.json")) 88 | } 89 | 90 | // Package Fields 91 | if (cmd.argv.hooks) { 92 | const pkgPath = api.dst("package.json") 93 | const pkgOpts = { cwd: api.dst(), normalize: false } 94 | const pkgBase = existsSync(pkgPath) ? readPkg.sync(pkgOpts) : {} 95 | const pkgData = JSON.parse(api.compile(api.tpl("pkg.json"))) 96 | await writePkg(api.dst(), merge(pkgBase, pkgData)) 97 | } 98 | 99 | // Root Files 100 | api.copy(api.tpl("rootfiles"), api.dst()) 101 | 102 | // Project Files 103 | const tplProjectDir = api.tpl(`projects/${cmd.argv.template}`) 104 | const tplProjectCfg = join(tplProjectDir, api.configFile) 105 | api.write(tplProjectCfg, api.dst(api.configFile)) 106 | api.copy(join(tplProjectDir, "src"), api.src()) 107 | api.copy(api.tpl("static"), api.src("static")) 108 | } 109 | }) 110 | -------------------------------------------------------------------------------- /packages/module/index.js: -------------------------------------------------------------------------------- 1 | import { getDefaultNuxtConfig } from "@nuxt/config" 2 | import { 3 | assoc, 4 | inject, 5 | insert, 6 | isNotNil, 7 | isNotEmpty, 8 | isNotFalse, 9 | preconnectLink 10 | } from "./utils" 11 | import copyIcon from "./icon" 12 | import defaults from "./defaults" 13 | import addESLint from "./eslint" 14 | import addPlugins from "./plugins" 15 | import meta from "./package.json" 16 | 17 | export default async function NuxtStack(options) { 18 | const stack = Object.assign({}, defaults.stack, this.options.stack, options) 19 | const config = inject(getDefaultNuxtConfig(), this.options) 20 | const unshift = config(insert("unshift"), true) 21 | const push = config(insert("push"), true) 22 | const assign = config(assoc) 23 | 24 | // Defaults 25 | assign("cache", true) 26 | assign("hardSource", true) 27 | 28 | // Styles 29 | if (isNotFalse(stack.normalizeCSS)) unshift("css", "normalize.css") 30 | push("css", this.options.styles) 31 | 32 | // Head: Language 33 | assign("head.htmlAttrs.lang", stack.lang) 34 | 35 | // Head: Preconnect Links 36 | if (isNotEmpty(stack.preconnect)) { 37 | unshift("head.link", stack.preconnect.map(preconnectLink)) 38 | } 39 | 40 | // Generate 41 | assign("generate.fallback", true) 42 | assign("generate.subFolders", false) 43 | 44 | // Messages 45 | assign("messages.back_to_home", "Return to home page") 46 | assign("messages.error_404", "Page not found") 47 | 48 | // Router 49 | assign("router.linkActiveClass", "link-active") 50 | assign("router.linkExactActiveClass", "link-active-exact") 51 | 52 | // Server 53 | assign("server.host", "0.0.0.0") 54 | assign("server.port", "5000") 55 | 56 | // Dotenv 57 | if (isNotFalse(this.options.dotenv)) { 58 | assign("dotenv.path", this.options.rootDir) 59 | 60 | this.requireModule({ 61 | src: "@nuxtjs/dotenv", 62 | options: this.options.dotenv 63 | }) 64 | } 65 | 66 | // Axios 67 | if (isNotNil(this.options.axios)) { 68 | this.requireModule({ 69 | src: "@nuxtjs/axios", 70 | options: this.options.axios 71 | }) 72 | } 73 | 74 | // PWA 75 | if (isNotFalse(this.options.pwa)) { 76 | assign("manifest.name", stack.name) 77 | assign("manifest.short_name", stack.shortName || stack.name) 78 | assign("manifest.description", stack.description) 79 | assign("manifest.theme_color", stack.themeColor) 80 | assign("manifest.background_color", stack.backgroundColor) 81 | 82 | assign("meta.lang", stack.lang) 83 | assign("meta.name", stack.name) 84 | assign("meta.ogHost", stack.host) 85 | assign("meta.description", stack.description) 86 | assign("meta.mobileAppIOS", true) 87 | 88 | if (isNotFalse(this.options.icon)) await copyIcon(this.options) 89 | 90 | this.requireModule({ 91 | src: "@nuxtjs/pwa", 92 | options: this.options 93 | }) 94 | } 95 | 96 | // Sitemap 97 | if (isNotFalse(this.options.sitemap)) { 98 | assign("sitemap.hostname", stack.host) 99 | assign("sitemap.generate", defaults.sitemap.generate) 100 | assign("sitemap.gzip", defaults.sitemap.gzip) 101 | 102 | this.requireModule({ 103 | src: "@nuxtjs/sitemap", 104 | options: this.options.sitemap 105 | }) 106 | } 107 | 108 | // Keywords 109 | if (isNotEmpty(stack.keywords)) { 110 | push("head.meta", { 111 | hid: "keywords", 112 | name: "keywords", 113 | content: stack.keywords.join(",") 114 | }) 115 | } 116 | 117 | // Style Resources 118 | if (isNotFalse(this.options.styleResources)) { 119 | push("styleResources.less", this.options.less) 120 | push("styleResources.sass", this.options.sass) 121 | push("styleResources.scss", this.options.scss) 122 | push("styleResources.stylus", this.options.styl) 123 | push("styleResources.stylus", this.options.stylus) 124 | 125 | this.requireModule({ 126 | src: "@nuxtjs/style-resources", 127 | options: this.options.styleResources 128 | }) 129 | } 130 | 131 | // SVG Loader 132 | if (isNotFalse(this.options.svgLoader)) { 133 | this.requireModule({ 134 | src: "nuxt-svg-loader", 135 | options: this.options.svgLoader 136 | }) 137 | } 138 | 139 | // Plugins 140 | addPlugins.call(this) 141 | 142 | // Build 143 | this.extendBuild(addESLint(this.options.eslint)) 144 | } 145 | 146 | export { meta } 147 | -------------------------------------------------------------------------------- /docs/guide/rationale.md: -------------------------------------------------------------------------------- 1 | # Rationale 2 | 3 | After developing a handful of Nuxt applications, you have probably found yourself referring back to previous projects to copy and paste stuff across. You've also probably installed and configured the same modules more than once. 4 | 5 | How many times have you copied across ESLint, Prettier, Jest or Babel configs? What about ignore files for these tools? Globbing patterns to lint and test your code? Configuring Husky and Lint Staged to put these tools to work before you commit your code? 6 | 7 | How many times have you installed `@nuxtjs/axios`, `@nuxtjs/pwa` or `webfontloader`? 8 | 9 | If the answer to some of these questions is "quite a few" then Nuxt Stack _might_ appeal to you with it's DRY (Don't Repeat Yourself) principles. 10 | 11 | ## Why nuxt-stack over create-nuxt-app? 12 | 13 | `create-nuxt-app` addresses many of these problems by providing a CLI for generating project templates with all the files, dependencies and configuration you need to get going. This saves a lot of time, but it veers away from the minimal origins of `nuxt` that makes it so awesome. 14 | 15 | There's something deeply satisfying about starting a new Nuxt project from scratch with nothing but `nuxt` as a dependency and a pages directory with a single `index.vue` file in it. There's so much going on behind the scenes when you run `nuxt` from the command line—but you barely need think about it. Nuxt takes care of wiring up Webpack, Babel and Vue for development _and_ production with routing, SSR and static site generation thrown in the mix. The DX (developer experience) is _fantastic_. 16 | 17 | However, as soon as you start integrating and configuring tools like ESLint, Prettier and Jest...or installing staple modules like `@nuxtjs/axios` and `@nuxtjs/pwa` Nuxt's zen starts to fade a little. 18 | 19 | Nuxt Stack attempts to remedy this by assembling a suite of [popular plugins](/module/plugins.html) and setting up the development tools needed to lint, format and test your application. 20 | 21 | But rather than flooding the project with files and dependencies, Nuxt Stack attempts to walk in Nuxt's footsteps by hiding away as much configuration as possible. Some config files are still required in order for your IDE to give you linting and formatting hints, but these configs are _very minimal_ since they inherit from Nuxt Stack presets like the ones below. 22 | 23 | ```js 24 | // .eslintrc.js 25 | module.exports = { 26 | extends: ["nuxt-stack"] 27 | } 28 | ``` 29 | 30 | ```js 31 | // .prettierrc.js 32 | module.exports = require("prettier-config-nuxt-stack") 33 | ``` 34 | 35 | The aspiration of Nuxt Stack is to complement the developer experience of Nuxt while delivering a highly performant yet minimal PWA template project out of the box. 36 | 37 | Much like Nuxt, every aspect of Nuxt Stack can be configured, turned on or off as required. If you don't like parts of the ESLint or Prettier config you can overwrite them. If you don't need some of the plugins you can disable them. The baseline configuration of Nuxt Stack is the result of developing numerous Nuxt applications and identifying the commonalities between them. 38 | 39 | Finally, Nuxt Stack adds a number of commands to Nuxt's CLI for performing common tasks such as linting, formatting and testing. Alongside `nuxt build` and `nuxt generate` you can do things like `nuxt lint`, `nuxt format` and `nuxt test`. These commands proxy to ESLint, Prettier and Jest respectively, but are preconfigured to work with the Nuxt app project structure, resolve path aliases and support Vue Single File Components when writing tests. 40 | 41 | ## Why SASS over Stylus or PostCSS? 42 | 43 | Prettier doesn't currently support Stylus and some flavours of PostCSS custom syntax. 44 | 45 | SASS was chosen as the default CSS preprocessor due to it's popularity, maturity, stability and formatting support from Prettier. 46 | 47 | What about LESS? Though Prettier does support LESS, [SASS is the more popular of the two][sass-vs-less]. 48 | 49 | ::: tip NOTE 50 | Nuxt Stack isn't doing anything special with SASS. It simply lists `node-sass` and `sass-loader` as dependencies so they don't need to be installed alongside `nuxt-stack`. This keeps project dependencies nice and lean from the outset. 51 | ::: 52 | 53 | If you're happy to forgo formatting from Prettier or would prefer to use LESS, simply install the CSS preprocessor and Webpack loader of your choosing as you normally would. 54 | 55 | ## Why Jest over AVA? 56 | 57 | 1. [Performance][jest-performance] 58 | 2. [Popularity][jest-popularity] 59 | 3. [Industry adoption][jest-adoption] 60 | 61 | [sass-vs-less]: https://trends.google.com/trends/explore?date=all&q=%2Fm%2F054k6n_,%2Fm%2F0gjd0jv 62 | [jest-performance]: https://blog.kentcdodds.com/migrating-to-jest-881f75366e7e 63 | [jest-popularity]: https://nodejs.libhunt.com/compare-jest-vs-ava-avajs 64 | [jest-adoption]: https://stackshare.io/stackups/ava-vs-jest#stacks 65 | -------------------------------------------------------------------------------- /docs/guide/features.md: -------------------------------------------------------------------------------- 1 | # Features 2 | 3 | Nuxt Stack is composed of two parts: 4 | 5 | - Nuxt [module](/module/) that installs and configures a collection of [modules and plugins](/module/plugins.html) 6 | - Suite of [commands](/commands/) added to Nuxt's CLI for testing, linting, formatting etc. 7 | 8 | ## Nuxt Stack Module 9 | 10 | - Prepends `normalize.css` to Nuxt's `css` array 11 | - Installs `node-sass` and `sass-loader` 12 | - Integrates `@nuxtjs/style-resources` 13 | - Adds a `styles` alias for `css` in Nuxt's config 14 | - Specify common meta data such as name, description and lang in one place and have it automatically cloned to head attributes, meta tags and the PWA manifest 15 | - Easily add `preconnect` links for improved resource fetching performance 16 | - Optimises Nuxt's `generate` config for Netlify with fallback enabled 17 | - Configures Nuxt's server host and port to work across the network so you can view your app on another device during development 18 | - ESLint integration with Webpack for linting and fixing your code automatically during development 19 | 20 | The `nuxt-stack` module also installs and configures the following modules and plugins: 21 | 22 | | Module | Description | 23 | | :----------------------------------------- | :------------------------------------------------------------------ | 24 | | [`@nuxtjs/axios`][nuxt-axios] | Nuxt `axios` module for making promise based HTTP requests | 25 | | [`@nuxtjs/dotenv`][nuxt-dotenv] | Loads `.env` file and merges the key pairs with Nuxt's `env` object | 26 | | [`@nuxtjs/pwa`][nuxt-pwa] | Collection of modules for developing PWAs | 27 | | [`@nuxtjs/sitemap`][nuxt-sitemap] | Automatically generate or serve a dynamic sitemap | 28 | | [`nuxt-svg-loader`][nuxt-svg-loader] | Import SVGs as Vue components | 29 | | [`webfontloader`][webfontloader] | Load custom webfonts from services like Google and Typekit | 30 | | [`vue-analytics`][vue-analytics] | Google Analytics integration for Vue and Nuxt | 31 | | [`lazysizes`][lazysizes] | Lazily load images and videos only when they become visible | 32 | | [`vue-pwa-installer`][vue-pwa-installer] | Interface for installing a PWA to the home screen | 33 | | [`vue-lazy-hydration`][vue-lazy-hydration] | Lazily hydrate Vue components using a variety of strategies | 34 | | [`vue-tabbing`][vue-tabbing] | Reactive flag triggered by keyboard navigation using the tab key | 35 | | [`vue-static-data`][vue-static-data] | Declare static (non-reactive) data within Vue components | 36 | 37 | ## Nuxt Stack Commands 38 | 39 | - Generate project templates with `nuxt init` 40 | - Pick from two templates: "basic" or "fancy" 41 | - Only essential files and configuration are generated 42 | - Options for specifying the source, build and statically generated site folders 43 | - Score 100/100 in a Google Lighthouse audit from the outset 44 | - Inject useful development `scripts` and hooks for `husky` and `lint-staged` 45 | - Generate VSCode settings for resolving Nuxt path aliases and formatting code on save 46 | - Write and run tests for Jest with zero configuration using `nuxt test` 47 | - Import Vue Single File Components (SFCs) into test files 48 | - Leverage `@vue/test-utils` suite of utilities for asserting your components 49 | - Use Jest's snapshot functions to render your Vue SFCs to formatted strings 50 | - Nuxt path aliases are automatically resolved 51 | - Only run _related_ tests when committing files to version control 52 | - Lint your source files using `nuxt lint` 53 | - Configures ESLint file extensions to match `js,jsx,ts,tsx,vue` 54 | - Format your code with Prettier using `nuxt format` 55 | - Optionally format and then lint with `nuxt format --lint` 56 | - Delete all generated files and folders with `nuxt clean` 57 | - Removes `.nuxt`, `dist` and `coverage` folders 58 | - Optionally delete `node_modules` and lock files 59 | - Serve statically generated sites with `nuxt serve` 60 | - Uses `serve` under the hood but infers the folder to serve from `nuxt.config.js` 61 | - Generate a Webpack Bundle Analyser report with `nuxt stats` 62 | 63 | [nuxt-axios]: https://axios.nuxtjs.org 64 | [nuxt-dotenv]: https://www.npmjs.com/package/@nuxtjs/dotenv 65 | [nuxt-pwa]: https://pwa.nuxtjs.org 66 | [nuxt-sitemap]: https://www.npmjs.com/package/@nuxtjs/sitemap 67 | [nuxt-svg-loader]: https://www.npmjs.com/package/nuxt-svg-loader 68 | [webfontloader]: https://www.npmjs.com/package/webfontloader 69 | [vue-analytics]: https://www.npmjs.com/package/vue-analytics 70 | [lazysizes]: https://www.npmjs.com/package/lazysizes 71 | [vue-pwa-installer]: https://www.npmjs.com/package/vue-pwa-installer 72 | [vue-lazy-hydration]: https://www.npmjs.com/package/vue-lazy-hydration 73 | [vue-tabbing]: https://www.npmjs.com/package/vue-tabbing 74 | [vue-static-data]: https://www.npmjs.com/package/vue-static-data 75 | -------------------------------------------------------------------------------- /docs/guide/readme.md: -------------------------------------------------------------------------------- 1 | # Guide 2 | 3 | Nuxt Stack is composed of two parts: 4 | 5 | - `nuxt-stack-cli` » Suite of Nuxt CLI [commands](/commands/) for linting, testing, formatting etc. 6 | - `nuxt-stack-module` » Nuxt [module](/module/) that installs and configures a collection of [plugins](/module/plugins.html) 7 | 8 | Though these packages can be installed separately, you will get the most out of Nuxt Stack by installing `nuxt-stack` which includes both. 9 | 10 | For a detailed rationale as to _why_ you might want to use Nuxt Stack [see here](./rationale.html). 11 | 12 | To get a detailed overview of the _features_ provided by Nuxt Stack [see here](./features.html). 13 | 14 | ## Getting started 15 | 16 | ```bash 17 | # Make a new directory 18 | mkdir example && cd example 19 | 20 | # Install dependencies 21 | yarn add nuxt nuxt-stack 22 | 23 | # Initialise a new project 24 | yarn nuxt init 25 | 26 | # Start the dev server 27 | yarn dev 28 | ``` 29 | 30 | Running `nuxt init` will generate a template project with all the files and configuration you need to get up and running. Take some time to look each of these files and appreciate the minimal contents of the obligatory dotfiles. 31 | 32 | When you're ready, open the URL printed in the terminal when you ran `yarn dev` and you should see a page that [looks like this][fancy-example]. 33 | 34 | This is the default "fancy" template that gets generated when you run `nuxt init` without any options. To see what options are available to you, check out the `init` [command docs](/commands/init.html). 35 | 36 | ::: tip 37 | For a completely stripped back project template you can run `nuxt init --template basic` 38 | 39 | If you're a [VSCode][vscode] user you'll want to add the `--vscode` flag to generate `jsconfig.json` and `.vscode/settings.json` files for resolving Nuxt path aliases and formatting your code when you save it. 40 | ::: 41 | 42 | To validate that the baseline app gets [100/100 on Google Lighthouse][google-lighthouse-report], run `yarn generate` and deploy the `dist` directory to a static site hosting service like Netlify. You can simply drag and drop the generated `dist` directory into Netlify. Copy and paste the URL generated by Netlify into Google's [web.dev](https://web.dev/measure) or run the audit locally from Chrome dev tool to see the results for yourself. 43 | 44 | ::: tip 45 | When running a Google Lighthouse audit locally, it is recommended that you do so in an incognito window since some Chrome extensions can impact the audit results. 46 | ::: 47 | 48 | ## Existing projects 49 | 50 | Though you can add `nuxt-stack` to an existing project, it is _highly recommended_ that you initialise one of the project templates if possible. This is because `nuxt init` generates all the config files you need to lint, format and test your app. It also injects some useful scripts into `package.json` while configuring `husky` and `lint-staged`. In addition to this, you might have dependencies listed in your `package.json` that are already included with `nuxt-stack` and don't need to be installed. 51 | 52 | With that said, follow these steps to integrate `nuxt-stack` into an existing project: 53 | 54 | 1. Create a feature branch in your project repo to sandbox the integration changes. 55 | 2. Move your project's `package.json` and `nuxt.config.js` along with any config and ignore files into a temporary directory. These should include: 56 | - Git: `.gitignore` 57 | - EditorConfig: `.editorconfig` 58 | - ESLint: `.eslintrc.js`, `.eslintignore` 59 | - Jest: `jest.config.js` 60 | - Prettier: `.prettierrc.js`, `.prettierignore` 61 | - Husky: `.huskyrc.js` 62 | - Lint Staged: `.lintstagedrc.js` 63 | - CommitLint: `.commitlintrc.js` 64 | - VSCode: `jsconfig.json`, `.vscode/settings.json` 65 | 3. Delete `node_modules` and any lock files (`yarn.lock` for example) 66 | 4. Run `yarn add nuxt nuxt-stack` from your repo root so a fresh `package.json` is created containing only a `dependencies` field with `nuxt` and `nuxt-stack` within it. 67 | 5. Now run `yarn nuxt init --template basic --src-dir ` where `` is the directory where your pages, components etc. are located. If your pages and components are located at the root of the repo, just pass the flag with no value afterwards eg. `nuxt init --src-dir`. If your pages, components etc. are in an "app" directory then pass `--src-dir app`. 68 | 69 | ::: warning NOTE 70 | The default source directory that Nuxt Stack configures when running `nuxt init` is "src" _not_ the root of your repo. This is because it's much easier to write globbing patterns to target source files when they're located in a folder. It also separates your Nuxt app source code from any api, docs, server or tests directories that might be located at the root of your repo. 71 | 72 | If you omit the `--src-dir` flag then a default value of `src` will be used. 73 | ::: 74 | 75 | 6. You should now have dotfiles for CommitLint, EditorConfig, ESLint, Git and Prettier as well as a minimal `nuxt.config.js` containing just `nuxt-stack` in the `modules` array. If you look at `package.json` you will find some `scripts` and configuration for `husky` and `lint-staged` have also been injected. 76 | 7. Your project now has the baseline configuration for Nuxt Stack—congratulations! 77 | 78 | ::: tip 79 | Grab a cup of tea. The next bit is going to be a little tedious. 80 | ::: 81 | 82 | 8. First things first—remove anything that you don't want to use. If you don't want to use CommitLint to lint your git commits, you can delete the `.commitlintrc.js` file and the `commit-msg` hook from the `husky` config in `package.json`. 83 | 9. You should then review Nuxt Stack's ESLint and Prettier configs to see if they are compatible or agreeable with your own. These can be found in the `packages` directory of the [Nuxt Stack repo][nuxt-stack-packages]. For example, you might prefer using single quotes over Prettier's default double quotes. These settings will be used to format and lint your code when you start making changes and committing it to version control. You can either adopt Nuxt Stack's defaults (recommended) and use the CLI to update all files for you, or modify the configs to your liking. 84 | 10. Copy and paste parts of your original `package.json` that you moved to a temporary directory over to the one generated when installing `nuxt` and `nuxt-stack`. You should copy across all the meta fields like name, description, repository, issues, license etc. If you had any Prettier, ESLint or Jest related fields in your original `package.json`, you should consider omitting those in favour of using the configuration files created by Nuxt Stack. Your call though! Think carefully when copying over your `scripts` since Nuxt Stack provides a number of new commands that might simplify the ones you had previously. Head over to the [commands docs](/commands/) to learn more. 85 | 86 | ::: tip 87 | Take some time to review Nuxt Stack's config files for ESLint, Prettier and Jest. They can all be found in the [repository packages folder][nuxt-stack-packages]. If you've setup ESLint or Jest to work with Nuxt before, these should look familiar to you. 88 | ::: 89 | 90 | 11. Install your project dependencies that are _not included_ with Nuxt Stack. You shouldn't need to install any dev dependencies for ESLint, Prettier, CommitLint, Husky, Lint Staged and Jest since `nuxt-stack-cli` already depends on these. To figure out what [dev]dependencies you should install, check out the [dependencies page](./dependencies.html). If your dependency isn't listed there, you should install it. 91 | 12. Finally, start copying over parts of your `nuxt.config.js`. However before you do, spend some time reading the [module](/module/) docs to understand what Nuxt Stack is doing and how you might be able to simplify your `nuxt.config.js` by using the `stack` options to define shared meta data like the `name` and `description` for your app. Chances are Nuxt Stack has already configured some of the things you might have done previously like integrating `eslint-loader` with Webpack. 92 | 93 | ::: tip 94 | Grab another tea, step outside, take a deep breath and smile. You made it. 95 | ::: 96 | 97 | [google-lighthouse-report]: https://lighthouse-dot-webdotdevsite.appspot.com/lh/html?url=https://fancy-example.nuxtstack.org 98 | [nuxt-stack-packages]: https://github.com/wagerfield/nuxt-stack/tree/master/packages 99 | [fancy-example]: https://fancy-example.nuxtstack.org 100 | [vscode]: https://code.visualstudio.com 101 | -------------------------------------------------------------------------------- /docs/module/configuration.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | ## Nuxt Stack Options 4 | 5 | ### `stack` 6 | 7 | Specify common meta data used by other modules in one place: 8 | 9 | ```js {3-6} 10 | export default { 11 | modules: ["nuxt-stack"], 12 | stack: { 13 | name: "Awesome Sauce", 14 | shortName: "Sausome" 15 | } 16 | } 17 | ``` 18 | 19 | | Key | Type | Default | 20 | | :---------------- | :--------- | :------------------------------ | 21 | | `lang` | `String` | `"en"` | 22 | | `host` | `URL` | `"https://nuxtstack.org/"` | 23 | | `name` | `String` | `"Nuxt Stack"` | 24 | | `shortName` | `String` | `stack.name` | 25 | | `description` | `String` | `"Stacks of goodness for Nuxt"` | 26 | | `keywords` | `String[]` | `["nuxt", "stack"]` | 27 | | `themeColor` | `String` | `"#4FC08D"` | 28 | | `backgroundColor` | `String` | `"#FFFFFF"` | 29 | 30 | The mapping of these values can be seen below: 31 | 32 | ```bash 33 | stack.lang » head.htmlAttrs.lang, meta.lang 34 | stack.host » meta.ogHost, sitemap.hostname 35 | stack.name » manifest.name, manifest.short_name, meta.name 36 | stack.description » manifest.description, meta.description 37 | stack.keywords » head.meta 38 | stack.themeColor » manifest.theme_color 39 | stack.backgroundColor » manifest.background_color 40 | ``` 41 | 42 | ::: warning IMPORTANT 43 | It is _highly recommended_ that you specify **host**, **name**, **description** and **keywords**. Otherwise your project will inherit the default values! 44 | ::: 45 | 46 | In addition to these mapping options: 47 | 48 | | Key | Type | Default | Description | 49 | | :------------- | :-------- | :------ | :------------------------------------------- | 50 | | `preconnect` | `URL[]` | `null` | Array of URLs to create preconnect links for | 51 | | `normalizeCSS` | `Boolean` | `true` | Whether or not to include `normalize.css` | 52 | 53 | ### `styles` 54 | 55 | Appended to Nuxt's `css` [options array][nuxt-css]. This was added for nothing more than semantics. You can choose to use `styles` in place of `css` if you would prefer to include SCSS or LESS files using a more general option key name :woman_shrugging: 56 | 57 | ```js {3-4} 58 | export default { 59 | modules: ["nuxt-stack"], 60 | styles: ["styles/a.scss"], 61 | css: ["styles/b.css"] 62 | } 63 | // The config above would result in nuxt.options.css: 64 | // ["normalize.css", "styles/b.css", "styles/a.scss"] 65 | ``` 66 | 67 | ### `eslint` 68 | 69 | By default `eslint-loader` is integrated with Webpack during development. ESLint will run against your code each time you save it and raise any linting errors in the terminal and browser console. It will also automatically fix linting errors where possible. 70 | 71 | To disable `eslint-loader` simply pass `false` to the `eslint` module options: 72 | 73 | ```js {3} 74 | export default { 75 | modules: ["nuxt-stack"], 76 | eslint: false 77 | } 78 | ``` 79 | 80 | Configuration options for `eslint-loader` can be [found here][eslint-loader-options] 81 | 82 | | Key | Type | Default | Description | 83 | | :------------ | :--------- | :---------- | :---------------------------------- | 84 | | `emitWarning` | `Boolean` | `true` | Emit all linting errors as warnings | 85 | | `cache` | `Boolean` | `true` | Cache linting results | 86 | | `fix` | `Boolean` | `true` | Automatically fix errors | 87 | | `formatter` | `Function` | `codeframe` | Linting error formatter | 88 | 89 | ```js {3-5} 90 | export default { 91 | modules: ["nuxt-stack"], 92 | eslint: { 93 | fix: false // disable automatic fixing 94 | } 95 | } 96 | ``` 97 | 98 | ## PWA Module Options 99 | 100 | `@nuxtjs/pwa` is installed by default. To prevent this module from being installed: 101 | 102 | ```js {3} 103 | export default { 104 | modules: ["nuxt-stack"], 105 | pwa: false 106 | } 107 | ``` 108 | 109 | Nuxt Stack configures some `@nuxtjs/pwa` module options using the `stack` options documented above. For example `stack.name` and `stack.description` are copied to `manifest.name`, `meta.name`, `manifest.description` and `meta.description` respectively. Specifying your app name, description, lang etc. in the `stack` module options follows DRY principles by keeping everything in one place. 110 | 111 | If you want different values in your app `manifest` to those in `meta` data, you can override the `stack` options by specifying the values in the respective PWA module options. `stack` options have the lowest order of precedence so they can be overridden by more specific module options. For example, if you set both `stack.name` and `meta.name` then `meta.name` will be used. 112 | 113 | Below is a quick reference table for the module options provided by Nuxt PWA: 114 | 115 | | Key | Type | Description | 116 | | :--------- | :-------- | :------------------------------------------------------------------------- | 117 | | `pwa` | `Boolean` | Set to `false` to prevent `@nuxtjs/pwa` from being installed | 118 | | `icon` | `Object` | See Nuxt PWA [icon docs](https://pwa.nuxtjs.org/modules/icon.html) | 119 | | `meta` | `Object` | See Nuxt PWA [meta docs](https://pwa.nuxtjs.org/modules/meta.html) | 120 | | `manifest` | `Object` | See Nuxt PWA [manifest docs](https://pwa.nuxtjs.org/modules/manifest.html) | 121 | | `workbox` | `Object` | See Nuxt PWA [workbox docs](https://pwa.nuxtjs.org/modules/workbox.html) | 122 | 123 | ## Third Party Module Options 124 | 125 | As documented on the [plugins page](./plugins.html), Nuxt Stack includes a suite of popular modules and plugins. Some of these are installed by default while others are only included when module options are specified in the Nuxt config. 126 | 127 | Below is a quick reference table of all the third party plugins that are included with Nuxt Stack. To configure or disable any of them, use the key specified. 128 | 129 | | Key | Description | 130 | | :--------------------------------------- | :---------------------------------------------------------------- | 131 | | [`axios`][nuxt-axios] | Nuxt `axios` integration for making promise based HTTP requests | 132 | | [`dotenv`][nuxt-dotenv] | Loads `.env` and merges the contents with Nuxt's `env` object | 133 | | [`ga`][vue-analytics] | Google Analytics integration for Nuxt | 134 | | [`hydration`][vue-lazy-hydration] | Lazily hydrate Vue components using a variety of strategies | 135 | | [`installer`][vue-pwa-installer] | Simple interface for installing a PWA to the home screen | 136 | | [`lazysizes`][lazysizes] | Lazily load images and videos when they become visible | 137 | | [`sitemap`][nuxt-sitemap] | Automatically generate or serve a dynamic sitemap | 138 | | [`styleResources`][nuxt-style-resources] | Share variables, mixins and functions across style files and SFCs | 139 | | [`staticData`][vue-static-data] | Declare static (non-reactive) data within Vue components | 140 | | [`svgLoader`][nuxt-svg-loader] | Import SVGs as Vue components | 141 | | [`tabbing`][vue-tabbing] | Reactive flag triggered by keyboard navigation using the tab key | 142 | | [`webfonts`][webfontloader] | Load custom webfonts from services like Google and Typekit | 143 | 144 | ## Example Config 145 | 146 | A typical `nuxt.config.js` might look something like this: 147 | 148 | ```js 149 | export default { 150 | srcDir: "src", 151 | modules: ["nuxt-stack"], 152 | stack: { 153 | host: "https://nuxtstack.org/", 154 | name: "Nuxt Stack", 155 | description: "Stacks of goodness for Nuxt", 156 | keywords: ["nuxt", "stack"], 157 | preconnect: ["https://fonts.gstatic.com", "https://fonts.googleapis.com"] 158 | }, 159 | ga: { 160 | id: "UA-123456789-1" 161 | }, 162 | axios: { 163 | baseURL: "https://api.nuxtstack.org/" 164 | }, 165 | webfonts: { 166 | google: { 167 | families: ["Quicksand:500", "Roboto Mono:400"] 168 | } 169 | }, 170 | styles: ["styles/index.scss"], 171 | styleResources: { 172 | scss: [ 173 | "styles/variables.scss", 174 | "styles/functions.scss", 175 | "styles/mixins.scss" 176 | ] 177 | } 178 | } 179 | ``` 180 | 181 | [eslint-loader-options]: https://github.com/webpack-contrib/eslint-loader#options 182 | [nuxt-css]: https://nuxtjs.org/api/configuration-css 183 | [nuxt-axios]: https://axios.nuxtjs.org 184 | [nuxt-dotenv]: https://www.npmjs.com/package/@nuxtjs/dotenv 185 | [nuxt-pwa]: https://pwa.nuxtjs.org 186 | [nuxt-sitemap]: https://www.npmjs.com/package/@nuxtjs/sitemap 187 | [nuxt-style-resources]: https://www.npmjs.com/package/@nuxtjs/style-resources 188 | [nuxt-svg-loader]: https://www.npmjs.com/package/nuxt-svg-loader 189 | [webfontloader]: https://www.npmjs.com/package/webfontloader 190 | [vue-analytics]: https://www.npmjs.com/package/vue-analytics 191 | [lazysizes]: https://www.npmjs.com/package/lazysizes 192 | [vue-pwa-installer]: https://www.npmjs.com/package/vue-pwa-installer 193 | [vue-lazy-hydration]: https://www.npmjs.com/package/vue-lazy-hydration 194 | [vue-tabbing]: https://www.npmjs.com/package/vue-tabbing 195 | [vue-static-data]: https://www.npmjs.com/package/vue-static-data 196 | --------------------------------------------------------------------------------