-
Notifications
You must be signed in to change notification settings - Fork 931
[Doc EN]: modules.md
review.
#267
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,69 +3,56 @@ title: Modules | |
description: Modules are Nuxt.js extensions which can extend it's core functionality and add endless integrations. | ||
--- | ||
|
||
> Modules are Nuxt.js extensions which can extend it's core functionality and add endless integrations. | ||
> Modules are Nuxt.js extensions which can extend it's core functionality and add endless integrations. | ||
|
||
## Introduction | ||
|
||
While developing production grade application using Nuxt, you will find out soon that nuxt core functionalities are not enough | ||
and writing configs and plugins for each project is a repetitive, boring and time consuming job. | ||
Also adding every new feature into Nuxt is not possible as it would make it a fat framework. | ||
|
||
This was the reason Nuxt introduces a higher order modular system to easily extend the core. | ||
Modules are basically **functions** which are called sequentially when booting Nuxt and core awaits for all of them | ||
to be finished before continue it's job. So they have the chance to customize almost any aspect of Nuxt and thanks to modular design of nuxt itself and Webpack [Tapable](https://github.com/webpack/tapable) technology they can also register hooks | ||
for certain entry points like builder initialization. | ||
While developing production grade application using Nuxt, you will find out soon that Nuxt core functionalities are not enough and writing configs and plugins for each project is a repetitive, boring and time consuming job. Also adding every new feature into Nuxt is not possible as it would make it a fat framework. | ||
|
||
Another point of using modules is that they can be refactored and packaged out of the project and released as NPM packages | ||
so you can share and use high quality integration and solutions from nuxt community with no pain! You might interested in modules if you: | ||
This was the reason Nuxt introduces a higher order modular system to easily extend the core. Modules are basically **functions** which are called sequentially when booting Nuxt and core awaits for all of them to be finished before continue it's job. So they have the chance to customize almost any aspect of Nuxt and thanks to modular design of Nuxt itself and webpack [Tapable](https://github.com/webpack/tapable) technology they can also register hooks for certain entry points like builder initialization. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One line Markdown convention. |
||
|
||
- Are a member of an **agile team** that want to set up your project instantly and avoid **re-inventing** the wheel for common tasks like google-analytics for your new project. | ||
Another point of using modules is that they can be refactored and packaged out of the project and released as npm packages so you can share and use high quality integration and solutions from Nuxt community with no pain! You might interested in modules if you: | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Return line Markdown convention. |
||
- Are a member of an **agile team** that want to set up your project instantly and avoid **re-inventing** the wheel for common tasks like Google Analytics tools for your new project. | ||
- Are an **enterprise** company which **quality** and **reusability** is important for your projects. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure @atinux but the usage of enterprise company is not redundant? Maybe documentation would say enterprise or company? I'm wrong XD? |
||
- Are a lovely **open source** enthusiast and interested in **sharing** your works with community in an easy manner. | ||
- Are a lazy programmer and don't like digging into details setting up every new library or integration. | ||
(Someone else should already provided a module for that but you can always ask community for making one) | ||
- Are a lovely **Open Source** enthusiast and interested in **sharing** your works with community in an easy manner. | ||
- Are a lazy programmer and don't like digging into details setting up every new library or integration (Someone else should already provided a module for that but you can always ask community for making one). | ||
- Tired of breaking low level API and Usage changes, and need **things that just work™**. | ||
|
||
|
||
## Write a basic Module | ||
As already mentioned modules are just simple functions. | ||
They can be packaged as NPM modules or directly included in project source code. | ||
|
||
As already mentioned modules are just simple functions. They can be packaged as npm modules or directly included in project source code. | ||
|
||
**modules/simple.js** | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Return line Markdown convention. |
||
```js | ||
module.exports = function SimpleModule (moduleOptions) { | ||
module.exports = function SimpleModule (moduleOptions) { | ||
// Write your code here | ||
} | ||
|
||
// REQUIRED if publishing as an NPM package | ||
// REQUIRED if publishing as an npm package | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. npm official term is all in lowercase |
||
// module.exports.meta = require('./package.json') | ||
``` | ||
|
||
**`moduleOptions`** | ||
|
||
This is the object passed using `modules` array by user we can use it to customize it's behavior. | ||
|
||
|
||
**`this.options`** | ||
|
||
You can directly access to Nuxt options using this reference. | ||
This is _nuxt.config.js_ with all default options assigned to and can be used for shared options between modules. | ||
|
||
You can directly access to Nuxt options using this reference. This is `nuxt.config.js` with all default options assigned to and can be used for shared options between modules. | ||
|
||
**`this.nuxt`** | ||
|
||
This is a reference to current nuxt instance. Refer to nuxt class docs for available methods. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One return line Markdown convention. |
||
This is a reference to current Nuxt instance. Refer to [Nuxt class docs for available methods](/api/internals-nuxt). | ||
|
||
**`this`** | ||
|
||
Context of modules. Refer to [ModuleContainer](/api/internals-module-container) class docs for available methods. | ||
|
||
**`module.exports.meta`** | ||
|
||
This line is **required** if you are publishing module as an NPM package. | ||
Nuxt internally uses meta to work better with your package. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One return line Markdown convention. |
||
This line is **required** if you are publishing module as an npm package. Nuxt internally uses meta to work better with your package. | ||
|
||
**nuxt.config.js** | ||
|
||
|
@@ -81,29 +68,21 @@ module.exports = { | |
} | ||
``` | ||
|
||
We then tell Nuxt to load some specific modules for a project with optional parameters as options. | ||
Please refer to [modules configuration](/api/configuration-modules) docs for more info! | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One return line Markdown convention. |
||
We then tell Nuxt to load some specific modules for a project with optional parameters as options. Please refer to [modules configuration](/api/configuration-modules) docs for more info! | ||
|
||
## Async Modules | ||
|
||
Not all modules will do everything synchronous. | ||
For example you may want to develop a module which needs fetching some API or doing async IO. | ||
For this, Nuxt supports async modules which can return a Promise or call a callback. | ||
Not all modules will do everything synchronous. For example you may want to develop a module which needs fetching some API or doing async IO. For this, Nuxt supports async modules which can return a Promise or call a callback. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One line Markdown convention. |
||
|
||
### Use async/await | ||
|
||
<p class="Alert Alert--orange"> | ||
Be aware that async/await is only supported in Node.js > 7.2 | ||
So if you are a module developer at least warn users about that if using them. | ||
For heavily async modules or better legacy support you can use either a bundler to transform it for older node comparability or using promise method. | ||
</p> | ||
<p class="Alert Alert--orange">Be aware that `async`/`await` is only supported in Node.js > 7.2. So if you are a module developer at least warn users about that if using them. For heavily async modules or better legacy support you can use either a bundler to transform it for older Node.js comparability or using promise method.</p> | ||
|
||
```js | ||
const fse = require('fs-extra') | ||
|
||
module.exports = async function asyncModule() { | ||
// You can do async works here using async/await | ||
// You can do async works here using `async`/`await` | ||
let pages = await fse.readJson('./pages.json') | ||
} | ||
``` | ||
|
@@ -117,7 +96,7 @@ module.exports = function asyncModule() { | |
return axios.get('https://jsonplaceholder.typicode.com/users') | ||
.then(res => res.data.map(user => '/users/' + user.username)) | ||
.then(routes => { | ||
// Do something by extending nuxt routes | ||
// Do something by extending Nuxt routes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Product name for Nuxt |
||
}) | ||
} | ||
``` | ||
|
@@ -140,8 +119,8 @@ module.exports = function asyncModule(callback) { | |
## Common Snippets | ||
|
||
### Top level options | ||
Sometimes it is more convenient if we can use top level options while register modules in `nuxt.config.js`. | ||
So we can combine multiply option sources. | ||
|
||
Sometimes it is more convenient if we can use top level options while register modules in `nuxt.config.js`. So we can combine multiply option sources. | ||
|
||
**nuxt.config.js** | ||
|
||
|
@@ -151,12 +130,12 @@ module.exports = { | |
'@nuxtjs/axios' | ||
], | ||
|
||
// axios module is aware of this by using this.options.axios | ||
// axios module is aware of this by using `this.options.axios` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tick for code, even in comment (because of Markdown is a language for plain text) |
||
axios: { | ||
option1, | ||
option2 | ||
} | ||
} | ||
} | ||
``` | ||
|
||
**module.js** | ||
|
@@ -169,11 +148,11 @@ module.exports = function (moduleOptions) { | |
``` | ||
|
||
### Provide plugins | ||
It is common that modules provide one or more plugins when added. | ||
For example [bootstrap-vue](https://bootstrap-vue.js.org) module would require to register itself into Vue. | ||
For this we can use `this.addPlugin` helper. | ||
|
||
It is common that modules provide one or more plugins when added. For example [bootstrap-vue](https://bootstrap-vue.js.org) module would require to register itself into Vue. For this we can use `this.addPlugin` helper. | ||
|
||
**plugin.js** | ||
|
||
```js | ||
import Vue from 'vue' | ||
import BootstrapVue from 'bootstrap-vue/dist/bootstrap-vue.esm' | ||
|
@@ -182,20 +161,22 @@ Vue.use(BootstrapVue) | |
``` | ||
|
||
**module.js** | ||
|
||
```js | ||
const path = require('path') | ||
|
||
module.exports = function nuxtBootstrapVue (moduleOptions) { | ||
// Register plugin.js template | ||
// Register `plugin.js` template | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tick in comment |
||
this.addPlugin(path.resolve(__dirname, 'plugin.js')) | ||
} | ||
``` | ||
|
||
### Template plugins | ||
Registered templates and plugins can leverage [lodash templates](https://lodash.com/docs/4.17.4#template) | ||
to conditionally change registered plugins output. | ||
|
||
Registered templates and plugins can leverage [lodash templates](https://lodash.com/docs/4.17.4#template) to conditionally change registered plugins output. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One line Markdown convention. |
||
|
||
**plugin.js** | ||
|
||
```js | ||
// Set Google Analytics UA | ||
ga('create', '<%= options.ua %>', 'auto') | ||
|
@@ -206,15 +187,16 @@ ga('create', '<%= options.ua %>', 'auto') | |
``` | ||
|
||
**module.js** | ||
|
||
```js | ||
const path = require('path') | ||
|
||
module.exports = function nuxtBootstrapVue (moduleOptions) { | ||
// Register plugin.js template | ||
// Register `plugin.js` template | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tick in comment |
||
this.addPlugin({ | ||
src: path.resolve(__dirname, 'plugin.js'), | ||
options: { | ||
// Nuxt will replace options.ua with 123 when copying plugin to project | ||
// Nuxt will replace `options.ua` with `123` when copying plugin to project | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tick in comment |
||
ua: 123, | ||
|
||
// conditional parts with dev will be stripped from plugin code on production builds | ||
|
@@ -225,33 +207,34 @@ module.exports = function nuxtBootstrapVue (moduleOptions) { | |
``` | ||
|
||
### Add a CSS library | ||
It is recommended checking if user already not provided same library to avoid adding duplicates. | ||
Also always consider having **an option to disable** adding css files by module. | ||
|
||
It is recommended checking if user already not provided same library to avoid adding duplicates. Also always consider having **an option to disable** adding css files by module. | ||
|
||
**module.js** | ||
|
||
```js | ||
module.exports = function (moduleOptions) { | ||
if (moduleOptions.fontAwesome !== false) { | ||
// Add font-awesome | ||
// Add Font Awesome | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Product name |
||
this.options.css.push('font-awesome/css/font-awesome.css') | ||
} | ||
} | ||
``` | ||
|
||
### Emit assets | ||
|
||
We can register webpack plugins to emit assets during build. | ||
|
||
**module.js** | ||
|
||
```js | ||
module.exports = function (moduleOptions) { | ||
const info = 'Built by awesome module - 1.3 alpha on ' + Date.now() | ||
const info = 'Built by awesome module - 1.3 alpha on ' + Date.now() | ||
|
||
this.options.build.plugins.push({ | ||
apply (compiler) { | ||
compiler.plugin('emit', (compilation, cb) => { | ||
|
||
// This will generate `.nuxt/dist/info.txt' with contents of info variable. | ||
// Source can be buffer too | ||
compilation.assets['info.txt'] = { source: () => info, size: () => info.length } | ||
|
@@ -265,14 +248,14 @@ module.exports = function (moduleOptions) { | |
|
||
### Register custom loaders | ||
|
||
We can do the same as `build.extend` in `nuxt.config.js` using `this.extendBuild` | ||
We can do the same as `build.extend` in `nuxt.config.js` using `this.extendBuild`. | ||
|
||
**module.js** | ||
|
||
```js | ||
module.exports = function (moduleOptions) { | ||
this.extendBuild((config, { isClient, isServer }) => { | ||
// .foo Loader | ||
// `.foo` Loader | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tick in comment |
||
config.module.rules.push({ | ||
test: /\.foo$/, | ||
use: [...] | ||
|
@@ -287,9 +270,8 @@ module.exports = function (moduleOptions) { | |
``` | ||
|
||
## Run Tasks on Specific hooks | ||
Your module may need to do things only on specific conditions not just during Nuxt initialization. | ||
We can use powerful [tapable](https://github.com/webpack/tapable) plugin system to do tasks on specific events. | ||
Nuxt will await for us if hooks return a Promise or are defined as `async`. | ||
|
||
Your module may need to do things only on specific conditions not just during Nuxt initialization. We can use powerful [Tapable](https://github.com/webpack/tapable) plugin system to do tasks on specific events. Nuxt will await for us if hooks return a Promise or are defined as `async`. | ||
|
||
```js | ||
module.exports = function () { | ||
|
@@ -305,7 +287,7 @@ module.exports = function () { | |
|
||
// Add hook for build | ||
this.nuxt.plugin('build', async builder => { | ||
// This Will be called once when builder created | ||
// This will be called once when builder created | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove capital |
||
|
||
// We can even register internal hooks here | ||
builder.plugin('compile', ({compiler}) => { | ||
|
@@ -315,12 +297,9 @@ module.exports = function () { | |
|
||
// Add hook for generate | ||
this.nuxt.plugin('generate', async generator => { | ||
// This Will be called when a nuxt generate starts | ||
// This will be called when a Nuxt generate starts | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove capital |
||
}) | ||
} | ||
``` | ||
|
||
<p class="Alert"> | ||
There are many many more hooks and possibilities for modules. | ||
Please refer to [Nuxt Internals](/api/internals) to learn more about Nuxt internal API. | ||
</p> | ||
<p class="Alert">There are many many more hooks and possibilities for modules. Please refer to [Nuxt Internals](/api/internals) to learn more about Nuxt internal API.</p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One line markdown convention |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One line Markdown convention.