diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 29c529f169..b0c6d276ed 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -83,16 +83,7 @@ module.exports = { }, { text: 'Plugins', - items: [ - { text: 'Babel', link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel' }, - { text: 'TypeScript', link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript' }, - { text: 'ESLint', link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint' }, - { text: 'PWA', link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa' }, - { text: 'Jest', link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-jest' }, - { text: 'Mocha', link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha' }, - { text: 'Cypress', link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-cypress' }, - { text: 'Nightwatch', link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-nightwatch' } - ] + link: '/core-plugins/' }, { text: 'Changelog', @@ -147,7 +138,22 @@ module.exports = { '/dev-guide/ui-localization.md' ] } - ] + ], + '/core-plugins/': [{ + title: 'Core Vue CLI Plugins', + collapsable: false, + children: [ + '/core-plugins/babel.md', + '/core-plugins/typescript.md', + '/core-plugins/eslint.md', + '/core-plugins/pwa.md', + '/core-plugins/unit-jest.md', + '/core-plugins/unit-mocha.md', + '/core-plugins/e2e-cypress.md', + '/core-plugins/e2e-nightwatch.md' + ] + }], + } }, '/zh/': { diff --git a/docs/core-plugins/README.md b/docs/core-plugins/README.md new file mode 100644 index 0000000000..1d62026f55 --- /dev/null +++ b/docs/core-plugins/README.md @@ -0,0 +1,14 @@ +# Plugins + +Vue CLI uses a plugin-based architecture. If you inspect a newly created project's `package.json`, you will find dependencies that start with `@vue/cli-plugin-`. Plugins can modify the internal webpack configuration and inject commands to `vue-cli-service`. Most of the features listed during the project creation process are implemented as plugins. + +This section contains documentation for core Vue CLI plugins: + +- [Babel](babel.md) +- [TypeScript](typescript.md) +- [ESLint](eslint.md) +- [PWA](pwa.md) +- [Jest](unit-jest.md) +- [Mocha](unit-mocha.md) +- [Cypress](e2e-cypress.md) +- [Nightwatch](e2e-nightwatch.md) diff --git a/docs/core-plugins/babel.md b/docs/core-plugins/babel.md new file mode 100644 index 0000000000..4bd37521af --- /dev/null +++ b/docs/core-plugins/babel.md @@ -0,0 +1,39 @@ +# @vue/cli-plugin-babel + +> babel plugin for vue-cli + +## Configuration + +Uses Babel 7 + `babel-loader` + [@vue/babel-preset-app](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/babel-preset-app) by default, but can be configured via `babel.config.js` to use any other Babel presets or plugins. + +By default, `babel-loader` excludes files inside `node_modules` dependencies. If you wish to explicitly transpile a dependency module, you will need to add it to the `transpileDependencies` option in `vue.config.js`: + +``` js +module.exports = { + transpileDependencies: [ + // can be string or regex + 'my-dep', + /other-dep/ + ] +} +``` + +## Caching + +[cache-loader](https://github.com/webpack-contrib/cache-loader) is enabled by default and cache is stored in `/node_modules/.cache/babel-loader`. + +## Parallelization + +[thread-loader](https://github.com/webpack-contrib/thread-loader) is enabled by default when the machine has more than 1 CPU cores. This can be turned off by setting `parallel: false` in `vue.config.js`. + +## Installing in an Already Created Project + +``` sh +vue add @vue/babel +``` + +## Injected webpack-chain Rules + +- `config.rule('js')` +- `config.rule('js').use('babel-loader')` +- `config.rule('js').use('cache-loader')` diff --git a/docs/core-plugins/e2e-cypress.md b/docs/core-plugins/e2e-cypress.md new file mode 100644 index 0000000000..e5e963a92c --- /dev/null +++ b/docs/core-plugins/e2e-cypress.md @@ -0,0 +1,48 @@ +# @vue/cli-plugin-e2e-cypress + +> e2e-cypress plugin for vue-cli + +This adds E2E testing support using [Cypress](https://www.cypress.io/). + +Cypress offers a rich interactive interface for running E2E tests, but currently only supports running the tests in Chromium. If you have a hard requirement on E2E testing in multiple browsers, consider using the Selenium-based [@vue/cli-plugin-e2e-nightwatch](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-nightwatch). + +## Injected Commands + +- **`vue-cli-service test:e2e`** + + Run e2e tests with `cypress run`. + + By default it launches Cypress in interactive mode with a GUI. If you want to run the tests in headless mode (e.g. for CI), you can do so with the `--headless` option. + + The command automatically starts a server in production mode to run the e2e tests against. If you want to run the tests multiple times without having to restart the server every time, you can start the server with `vue-cli-service serve --mode production` in one terminal, and then run e2e tests against that server using the `--url` option. + + Options: + + ``` + --headless run in headless mode without GUI + --mode specify the mode the dev server should run in. (default: production) + --url run e2e tests against given url instead of auto-starting dev server + -s, --spec (headless only) runs a specific spec file. defaults to "all" + ``` + + Additionally: + + - In GUI mode, [all Cypress CLI options for `cypress open` are also supported](https://docs.cypress.io/guides/guides/command-line.html#cypress-open); + - In `--headless` mode, [all Cypress CLI options for `cypress run` are also supported](https://docs.cypress.io/guides/guides/command-line.html#cypress-run). + + Examples : + - Run Cypress in headless mode for a specific file: `vue-cli-service test:e2e --headless --spec tests/e2e/specs/actions.spec.js` + +## Configuration + +We've pre-configured Cypress to place most of the e2e testing related files under `/tests/e2e`. You can also check out [how to configure Cypress via `cypress.json`](https://docs.cypress.io/guides/references/configuration.html#Options). + +## Environment Variables + +Cypress doesn't load .env files for your test files the same way as `vue-cli` does for your [application code](https://cli.vuejs.org/guide/mode-and-env.html#using-env-variables-in-client-side-code). Cypress supports a few ways to [define env variables](https://docs.cypress.io/guides/guides/environment-variables.html#) but the easiest one is to use .json files (either `cypress.json` or `cypress.env.json`) to define environment variables. Keep in mind those variables are accessible via `Cypress.env` function instead of regular `process.env` object. + +## Installing in an Already Created Project + +``` sh +vue add @vue/e2e-cypress +``` diff --git a/docs/core-plugins/e2e-nightwatch.md b/docs/core-plugins/e2e-nightwatch.md new file mode 100644 index 0000000000..bbced35a28 --- /dev/null +++ b/docs/core-plugins/e2e-nightwatch.md @@ -0,0 +1,37 @@ +# @vue/cli-plugin-e2e-nightwatch + +> e2e-nightwatch plugin for vue-cli + +## Injected Commands + +- **`vue-cli-service test:e2e`** + + run e2e tests with [NightwatchJS](http://nightwatchjs.org). + + Options: + + ``` + --url run e2e tests against given url instead of auto-starting dev server + --config use custom nightwatch config file (overrides internals) + -e, --env specify comma-delimited browser envs to run in (default: chrome) + -t, --test specify a test to run by name + -f, --filter glob to filter tests by filename + ``` + + > Note: this plugin currently uses Nightwatch v0.9.x. We are waiting for Nightwatch 1.0 to stabilize before upgrading. + + Additionally, [all Nightwatch CLI options are also supported](https://github.com/nightwatchjs/nightwatch/blob/master/lib/runner/cli/cli.js). + +## Configuration + +We've pre-configured Nightwatch to run with Chrome by default. If you wish to run e2e tests in additional browsers, you will need to add a `nightwatch.config.js` or `nightwatch.json` in your project root to configure additional browsers. The config will be merged into the [internal Nightwatch config](https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-plugin-e2e-nightwatch/nightwatch.config.js). + +Alternatively, you can completely replace the internal config with a custom config file using the `--config` option. + +Consult Nightwatch docs for [configuration options](http://nightwatchjs.org/gettingstarted#settings-file) and how to [setup browser drivers](http://nightwatchjs.org/gettingstarted#browser-drivers-setup). + +## Installing in an Already Created Project + +``` sh +vue add @vue/e2e-nightwatch +``` diff --git a/docs/core-plugins/eslint.md b/docs/core-plugins/eslint.md new file mode 100644 index 0000000000..fb07db7150 --- /dev/null +++ b/docs/core-plugins/eslint.md @@ -0,0 +1,72 @@ +# @vue/cli-plugin-eslint + +> eslint plugin for vue-cli + +## Injected Commands + +- **`vue-cli-service lint`** + + ``` + Usage: vue-cli-service lint [options] [...files] + + Options: + + --format [formatter] specify formatter (default: codeframe) + --no-fix do not fix errors + --max-errors specify number of errors to make build failed (default: 0) + --max-warnings specify number of warnings to make build failed (default: Infinity) + ``` + + Lints and fixes files. If no specific files are given, it lints all files in `src` and `test`. + + Other [ESLint CLI options](https://eslint.org/docs/user-guide/command-line-interface#options) are also supported. + +## Configuration + +ESLint can be configured via `.eslintrc` or the `eslintConfig` field in `package.json`. + +Lint-on-save during development with `eslint-loader` is enabled by default. It can be disabled with the `lintOnSave` option in `vue.config.js`: + +``` js +module.exports = { + lintOnSave: false +} +``` + +When set to `true`, `eslint-loader` will emit lint errors as warnings. By default, warnings are only logged to the terminal and does not fail the compilation. + +To make lint errors show up in the browser overlay, you can use `lintOnSave: 'error'`. This will force `eslint-loader` to always emit errors. this also means lint errors will now cause the compilation to fail. + +Alternatively, you can configure the overlay to display both warnings and errors: + +``` js +// vue.config.js +module.exports = { + devServer: { + overlay: { + warnings: true, + errors: true + } + } +} +``` + +When `lintOnSave` is a truthy value, `eslint-loader` will be applied in both development and production. If you want to disable `eslint-loader` during production build, you can use the following config: + +``` js +// vue.config.js +module.exports = { + lintOnSave: process.env.NODE_ENV !== 'production' +} +``` + +## Installing in an Already Created Project + +``` sh +vue add @vue/eslint +``` + +## Injected webpack-chain Rules + +- `config.module.rule('eslint')` +- `config.module.rule('eslint').use('eslint-loader')` diff --git a/docs/core-plugins/pwa.md b/docs/core-plugins/pwa.md new file mode 100644 index 0000000000..51c46b7098 --- /dev/null +++ b/docs/core-plugins/pwa.md @@ -0,0 +1,135 @@ +# @vue/cli-plugin-pwa + +> pwa plugin for vue-cli + +The service worker added with this plugin is only enabled in the production environment (e.g. only if you run `npm run build` or `yarn build`). Enabling service worker in a development mode is not a recommended practice, because it can lead to the situation when previously cached assets are used and the latest local changes are not included. + +Instead, in the development mode the `noopServiceWorker.js` is included. This service worker file is effectively a 'no-op' that will reset any previous service worker registered for the same host:port combination. + +If you need to test a service worker locally, build the application and run a simple HTTP-server from your build directory. It's recommended to use a browser incognito window to avoid complications with your browser cache. + +## Configuration + +Configuration is handled via the `pwa` property of either the `vue.config.js` +file, or the `"vue"` field in `package.json`. + +- **pwa.workboxPluginMode** + + This allows you to the choose between the two modes supported by the underlying + [`workbox-webpack-plugin`](https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin). + + - `'GenerateSW'` (default), will lead to a new service worker file being created + each time you rebuild your web app. + + - `'InjectManifest'` allows you to start with an existing service worker file, + and creates a copy of that file with a "precache manifest" injected into it. + + The "[Which Plugin to Use?](https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#which_plugin_to_use)" + guide can help you choose between the two modes. + +- **pwa.workboxOptions** + + These options are passed on through to the underlying `workbox-webpack-plugin`. + + For more information on what values are supported, please see the guide for + [`GenerateSW`](https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#full_generatesw_config) + or for [`InjectManifest`](https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#full_injectmanifest_config). + +- **pwa.name** + + - Default: "name" field in `package.json` + + Used as the value for the `apple-mobile-web-app-title` meta tag in the generated HTML. Note you will need to edit `public/manifest.json` to match this. + +- **pwa.themeColor** + + - Default: `'#4DBA87'` + +- **pwa.msTileColor** + + - Default: `'#000000'` + +- **pwa.appleMobileWebAppCapable** + + - Default: `'no'` + + This defaults to `'no'` because iOS before 11.3 does not have proper PWA support. See [this article](https://medium.com/@firt/dont-use-ios-web-app-meta-tag-irresponsibly-in-your-progressive-web-apps-85d70f4438cb) for more details. + +- **pwa.appleMobileWebAppStatusBarStyle** + + - Default: `'default'` + +- **pwa.assetsVersion** + + - Default: `''` + + This option is used if you need to add a version to your icons and manifest, against browser’s cache. This will append `?v=` to the URLs of the icons and manifest. + +- **pwa.manifestPath** + + - Default: `'manifest.json'` + + The path of app’s manifest. + +- **pwa.manifestOptions** + + - Default: `{}` + + The object will be used to generate the `manifest.json` + + If the following attributes are not defined in the object, the options of `pwa` or default options will be used instead. + - name: `pwa.name` + - short_name: `pwa.name` + - start_url: `'.'` + - display: `'standalone'` + - theme_color: `pwa.themeColor` + +- **pwa.iconPaths** + + - Defaults: + + ```js + { + favicon32: 'img/icons/favicon-32x32.png', + favicon16: 'img/icons/favicon-16x16.png', + appleTouchIcon: 'img/icons/apple-touch-icon-152x152.png', + maskIcon: 'img/icons/safari-pinned-tab.svg', + msTileImage: 'img/icons/msapplication-icon-144x144.png' + } + ``` + + Change these values to use different paths for your icons. + +### Example Configuration + +```js +// Inside vue.config.js +module.exports = { + // ...other vue-cli plugin options... + pwa: { + name: 'My App', + themeColor: '#4DBA87', + msTileColor: '#000000', + appleMobileWebAppCapable: 'yes', + appleMobileWebAppStatusBarStyle: 'black', + + // configure the workbox plugin + workboxPluginMode: 'InjectManifest', + workboxOptions: { + // swSrc is required in InjectManifest mode. + swSrc: 'dev/sw.js', + // ...other Workbox options... + } + } +} +``` + +## Installing in an Already Created Project + +``` sh +vue add @vue/pwa +``` + +## Injected webpack-chain Rules + +- `config.plugin('workbox')` diff --git a/docs/core-plugins/typescript.md b/docs/core-plugins/typescript.md new file mode 100644 index 0000000000..dedbbbcbb0 --- /dev/null +++ b/docs/core-plugins/typescript.md @@ -0,0 +1,39 @@ +# @vue/cli-plugin-typescript + +> typescript plugin for vue-cli + +Uses TypeScript + `ts-loader` + [fork-ts-checker-webpack-plugin](https://github.com/Realytics/fork-ts-checker-webpack-plugin) for faster off-thread type checking. + +## Configuration + +TypeScript can be configured via `tsconfig.json`. + +Since `3.0.0-rc.6`, `typescript` is now a peer dependency of this package, so you can use a specific version of TypeScript by updating your project's `package.json`. + +This plugin can be used alongside `@vue/cli-plugin-babel`. When used with Babel, this plugin will output ES2015 and delegate the rest to Babel for auto polyfill based on browser targets. + +## Injected Commands + +If opted to use [TSLint](https://palantir.github.io/tslint/) during project creation, `vue-cli-service lint` will be injected. + +## Caching + +[cache-loader](https://github.com/webpack-contrib/cache-loader) is enabled by default and cache is stored in `/node_modules/.cache/ts-loader`. + +## Parallelization + +[thread-loader](https://github.com/webpack-contrib/thread-loader) is enabled by default when the machine has more than 1 CPU cores. This can be turned off by setting `parallel: false` in `vue.config.js`. + +## Installing in an Already Created Project + +``` sh +vue add @vue/typescript +``` + +## Injected webpack-chain Rules + +- `config.rule('ts')` +- `config.rule('ts').use('ts-loader')` +- `config.rule('ts').use('babel-loader')` (when used alongside `@vue/cli-plugin-babel`) +- `config.rule('ts').use('cache-loader')` +- `config.plugin('fork-ts-checker')` diff --git a/docs/core-plugins/unit-jest.md b/docs/core-plugins/unit-jest.md new file mode 100644 index 0000000000..7aabbbd547 --- /dev/null +++ b/docs/core-plugins/unit-jest.md @@ -0,0 +1,70 @@ +# @vue/cli-plugin-unit-jest + +> unit-jest plugin for vue-cli + +## Injected Commands + +- **`vue-cli-service test:unit`** + + Run unit tests with Jest. Default `testMatch` is `/(tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx))` which matches: + + - Any files in `tests/unit` that end in `.spec.(js|jsx|ts|tsx)`; + - Any js(x)/ts(x) files inside `__tests__` directories. + + Usage: `vue-cli-service test:unit [options] ` + + All [Jest command line options](https://facebook.github.io/jest/docs/en/cli.html) are also supported. + +## Debugging Tests + +Note that directly running `jest` will fail because the Babel preset requires hints to make your code work in Node.js, so you must run your tests with `vue-cli-service test:unit`. + +If you want to debug your tests via the Node inspector, you can run the following: + +```sh +# macOS or linux +node --inspect-brk ./node_modules/.bin/vue-cli-service test:unit + +# Windows +node --inspect-brk ./node_modules/@vue/cli-service/bin/vue-cli-service.js test:unit +``` + +## Configuration + +Jest can be configured via `jest.config.js` in your project root, or the `jest` field in `package.json`. + +## Installing in an Already Created Project + +```sh +vue add @vue/unit-jest +``` + +## Transform dependencies from `/node_modules` + +By default, jest doesn't transform anything from `/node_modules`. + +Since jest runs in node, we also don't have to transpile anything that uses modern ECMAScript features as Node >=8 already supports these features, so it's a sensible default. cli-plugin-jest also doesn't respect the `transpileDependencies` option in `vue.config.js` for the same reason. + +However, we have (at least) three cases where we do need to transpile code from `/node_modules` in jest: + +1. Usage of ES6 `import`/`export` statements, which have to be compiled to commonjs `module.exports` +2. Single File Components (`.vue` files) which have to be run through `vue-jest` +3. Typescript code + +To do this, we need to add an exception to the `transformIgnorePatterns` option of jest. This is its default value: + +```javascript +transformIgnorePatterns: ['/node_modules/'] +``` + +We have to add exceptions to this pattern with a RegExp negative lookahead: + +```javascript +transformIgnorePatterns: ['/node_modules/(?!name-of-lib-o-transform)'] +``` + +To exclude multiple libraries: + +```javascript +transformIgnorePatterns: ['/node_modules/(?!lib-to-transform|other-lib)'] +``` diff --git a/docs/core-plugins/unit-mocha.md b/docs/core-plugins/unit-mocha.md new file mode 100644 index 0000000000..f1bb0ca706 --- /dev/null +++ b/docs/core-plugins/unit-mocha.md @@ -0,0 +1,36 @@ +# @vue/cli-plugin-unit-mocha + +> unit-mocha plugin for vue-cli + +## Injected Commands + +- **`vue-cli-service test:unit`** + + Run unit tests with [mocha-webpack](https://github.com/zinserjan/mocha-webpack) + [chai](http://chaijs.com/). + + **Note the tests are run inside Node.js with browser environment simulated with JSDOM.** + + ``` + Usage: vue-cli-service test:unit [options] [...files] + + Options: + + --watch, -w run in watch mode + --grep, -g only run tests matching + --slow, -s "slow" test threshold in milliseconds + --timeout, -t timeout threshold in milliseconds + --bail, -b bail after first test failure + --require, -r require the given module before running tests + --include include the given module into test bundle + --inspect-brk Enable inspector to debug the tests + ``` + + Default files matches are: any files in `tests/unit` that end in `.spec.(ts|js)`. + + All [mocha-webpack command line options](http://zinserjan.github.io/mocha-webpack/docs/installation/cli-usage.html) are also supported. + +## Installing in an Already Created Project + +``` sh +vue add @vue/unit-mocha +``` diff --git a/package.json b/package.json index aeb46fbd60..69d1bf0eb1 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "sync": "node scripts/syncDeps.js", "boot": "node scripts/bootstrap.js", "release": "yarn --pure-lockfile && yarn clean && node scripts/release.js", - "version": "node scripts/genChangelog.js && git add CHANGELOG.md", + "version": "node scripts/genChangelog.js && node scripts/genDocs.js && git add CHANGELOG.md && git add docs", "docs": "vuepress dev docs", "docs:build": "vuepress build docs", "patch-chromedriver": "node scripts/patchChromedriver.js" diff --git a/scripts/genDocs.js b/scripts/genDocs.js new file mode 100644 index 0000000000..6f387d8893 --- /dev/null +++ b/scripts/genDocs.js @@ -0,0 +1,27 @@ +const fs = require('fs') +const path = require('path') + +const pluginsDirPath = path.resolve(__dirname, '../packages', '@vue') +const pluginRegEx = new RegExp('cli-plugin-') + +function generatePluginDoc (plugin) { + const entryPath = path.resolve(__dirname, '../packages', '@vue', plugin, 'README.md') + const entryContent = fs.readFileSync(entryPath) + const docPath = path.resolve(__dirname, '../docs', 'core-plugins', `${plugin.replace('cli-plugin-', '')}.md`) + fs.writeFile(docPath, entryContent, () => { }) +} + +const genDocs = (module.exports = async () => { + fs.readdir(pluginsDirPath, (_, files) => { + files.forEach(file => { + if (pluginRegEx.test(file)) { + generatePluginDoc(file) + } + }) + }) +}) + +genDocs().catch(err => { + console.error(err) + process.exit(1) +})