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 |
2 |
3 |
4 |
5 |
6 | Nuxt
7 | Stack
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
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 |
15 |
--------------------------------------------------------------------------------
/docs/.vuepress/public/logo.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/packages/templates/projects/fancy/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
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 |
--------------------------------------------------------------------------------