mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-04-22 20:38:55 -05:00
chore: merge branch 'dev' into docs [ci skip]
This commit is contained in:
@@ -8,6 +8,9 @@ module.exports = {
|
||||
env: {
|
||||
"jest": true
|
||||
},
|
||||
globals: {
|
||||
name: 'off'
|
||||
},
|
||||
rules: {
|
||||
"indent": ["error", 2, {
|
||||
"MemberExpression": "off"
|
||||
|
||||
@@ -8,3 +8,4 @@ temp
|
||||
.vuerc
|
||||
.version
|
||||
.versions
|
||||
.changelog
|
||||
|
||||
+123
@@ -1,3 +1,126 @@
|
||||
|
||||
## 3.6.0 (2019-04-13)
|
||||
|
||||
#### :rocket: New Feature
|
||||
* `@vue/cli-ui`
|
||||
* [#3688](https://github.com/vuejs/vue-cli/pull/3688) add "copy content to clipboard" button on terminal component ([@pikax](https://github.com/pikax))
|
||||
* [c81e6c](https://github.com/vuejs/vue-cli/commit/c81e6c21a20d66bfa66a664d94ec3ccc81c54d38) **project create**: bare option ([@Akryum](https://github.com/Akryum))
|
||||
* [08de713](https://github.com/vuejs/vue-cli/commit/08de713598530bbc85282c6853bffebb912142a3) **plugin add**: feature icons ([@Akryum](https://github.com/Akryum))
|
||||
* [fbfbd29](https://github.com/vuejs/vue-cli/commit/fbfbd29be5b3c2f07adb1c8db45ba18cd28468a5) vulnerability audit widget ([@Akryum](https://github.com/Akryum))
|
||||
* [40d9346](https://github.com/vuejs/vue-cli/commit/40d9346914b3416bf3e6265fd020f6be768c9543) **api**: save shared data to disk ([@Akryum](https://github.com/Akryum))
|
||||
* [ca2bdad](https://github.com/vuejs/vue-cli/commit/ca2bdadb028ee0496e1cf64cca4be2a6cb591547) **tasks**: refresh button ([@Akryum](https://github.com/Akryum))
|
||||
* `@vue/cli-service`
|
||||
* [#3703](https://github.com/vuejs/vue-cli/pull/3703) add `--filename` option to specify the output file name ([@NickeyLin](https://github.com/NickeyLin))
|
||||
* [#3760](https://github.com/vuejs/vue-cli/pull/3760) bundle currentScript polyfill by default if library needs IE support ([@sodatea](https://github.com/sodatea))
|
||||
* [#3595](https://github.com/vuejs/vue-cli/pull/3595) support multi-main entry in pages config ([@sodatea](https://github.com/sodatea))
|
||||
* [#3663](https://github.com/vuejs/vue-cli/pull/3663) support pug as html template ([@sodatea](https://github.com/sodatea))
|
||||
* `@vue/cli`
|
||||
* [#3568](https://github.com/vuejs/vue-cli/pull/3568) add makeJSOnlyValue to generator API. Provides convenien… ([@steveworkman](https://github.com/steveworkman))
|
||||
* [#3643](https://github.com/vuejs/vue-cli/pull/3643) do not write undefined fields to config files ([@sodatea](https://github.com/sodatea))
|
||||
* `@vue/cli-service`, `@vue/cli-shared-utils`, `@vue/cli-ui`, `@vue/cli`
|
||||
* [#1531](https://github.com/vuejs/vue-cli/pull/1531) support PNPM as a package manager ([@robertkruis](https://github.com/robertkruis))
|
||||
* [#3790](https://github.com/vuejs/vue-cli/pull/3790) fix PNPM compatibility issues during scaffolding ([@sodatea](https://github.com/sodatea))
|
||||
* `@vue/cli-plugin-eslint`, `@vue/cli-service`
|
||||
* [#3572](https://github.com/vuejs/vue-cli/pull/3572) add 3rd option to `lintOnSave` to support 'default' behaviour (Closes [#3552](https://github.com/vuejs/vue-cli/issues/3552)) ([@LinusBorg](https://github.com/LinusBorg))
|
||||
* `@vue/cli-plugin-unit-jest`
|
||||
* [#3589](https://github.com/vuejs/vue-cli/pull/3589) add jest typeahead plugin ([@sodatea](https://github.com/sodatea))
|
||||
|
||||
#### :bug: Bug Fix
|
||||
* `@vue/cli-ui`
|
||||
* [8c3ff11](https://github.com/vuejs/vue-cli/commit/8c3ff1165384bf4bafca39a267e3da3d9821abdb) **project create**: run vue create in child process, closes #3664 ([@Akryum](https://github.com/Akryum))
|
||||
* [dac7a4b](https://github.com/vuejs/vue-cli/commit/dac7a4bf743a42befb119c1b0ab7992c73fec766) **project manager**: ake open in editor button more discoverable ([@Akryum](https://github.com/Akryum))
|
||||
* [fd9cb16](https://github.com/vuejs/vue-cli/commit/fd9cb1628e04cd30a01cab0b5591bab7669768d7) **widget**: make resize handles more visible ([@Akryum](https://github.com/Akryum))
|
||||
* [c4bd1ab](https://github.com/vuejs/vue-cli/commit/c4bd1abea80fbd30d359812da8f88b12e9fca48b) set cache-control header on static files ([@Akryum](https://github.com/Akryum))
|
||||
|
||||
#### :house: Internal
|
||||
* `@vue/cli-service`
|
||||
* [#2405](https://github.com/vuejs/vue-cli/pull/2405) remove unused `placeAtRootIfRelative` parameter ([@dailyvuejs](https://github.com/dailyvuejs))
|
||||
* [#3707](https://github.com/vuejs/vue-cli/pull/3707) more accurate vim swap file ignore ([@Newbrict](https://github.com/Newbrict))
|
||||
* [#3709](https://github.com/vuejs/vue-cli/pull/3709) use high resolution version of favicon.ico ([@phanan](https://github.com/phanan))
|
||||
* [#3628](https://github.com/vuejs/vue-cli/pull/3628) make `fibers` opt-in for dart sass ([@sodatea](https://github.com/sodatea))
|
||||
* `@vue/cli-ui`
|
||||
* [#3778](https://github.com/vuejs/vue-cli/pull/3778) **refactor(plugin)**: invoke is now done in child process ([@Akryum](https://github.com/Akryum))
|
||||
* [4f0286c](https://github.com/vuejs/vue-cli/commit/4f0286c5535e87d5303feed52ba662082ef0296b) **perf(webpack dashboard)**: cleaning the analyzer data ([@Akryum](https://github.com/Akryum))
|
||||
* [ecd64c4](https://github.com/vuejs/vue-cli/commit/ecd64c43a620a3573ee37e933cac0e8429f009c1) **perf(task details)**: better defering ([@Akryum](https://github.com/Akryum))
|
||||
* [13199f5](https://github.com/vuejs/vue-cli/commit/13199f52e1e227bc1a720fb95c913564b8241e88) **tasks**: sort ([@Akryum](https://github.com/Akryum))
|
||||
|
||||
* Other
|
||||
* [#3650](https://github.com/vuejs/vue-cli/pull/3650) workflow: use lerna-changelog ([@sodatea](https://github.com/sodatea))
|
||||
|
||||
#### Committers: 10
|
||||
- Carlos Rodrigues ([@pikax](https://github.com/pikax))
|
||||
- Dimitar Dimitrov ([@Newbrict](https://github.com/Newbrict))
|
||||
- Guillaume Chau ([@Akryum](https://github.com/Akryum))
|
||||
- Haoqun Jiang ([@sodatea](https://github.com/sodatea))
|
||||
- Nick ([@NickeyLin](https://github.com/NickeyLin))
|
||||
- Phan An ([@phanan](https://github.com/phanan))
|
||||
- Steve Workman ([@steveworkman](https://github.com/steveworkman))
|
||||
- Thorsten Lünborg ([@LinusBorg](https://github.com/LinusBorg))
|
||||
- [@dailyvuejs](https://github.com/dailyvuejs)
|
||||
- [@robertkruis](https://github.com/robertkruis)
|
||||
|
||||
|
||||
# [3.5.5](https://github.com/vuejs/vue-cli/compare/v3.5.4...v3.5.5) (2019-04-01)
|
||||
|
||||
## babel-preset-app
|
||||
|
||||
#### Reverts
|
||||
|
||||
* "fix: should not add polyfills from transform-runtime plugin ([#3730](https://github.com/vuejs/vue-cli/issues/3730))" ([#3742](https://github.com/vuejs/vue-cli/issues/3742)) ([7228146](https://github.com/vuejs/vue-cli/commit/7228146)), closes [#3741](https://github.com/vuejs/vue-cli/issues/3741)
|
||||
|
||||
|
||||
|
||||
# [3.5.4](https://github.com/vuejs/vue-cli/compare/v3.5.3...v3.5.4) (2019-03-31)
|
||||
|
||||
## babel-preset-app
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* should not add polyfills from transform-runtime plugin ([#3730](https://github.com/vuejs/vue-cli/issues/3730)) ([b987969](https://github.com/vuejs/vue-cli/commit/b987969))
|
||||
* should not use abosulte polyfill paths when `absoluteRuntime` is on ([#3732](https://github.com/vuejs/vue-cli/issues/3732)) ([9bdff3b](https://github.com/vuejs/vue-cli/commit/9bdff3b)), closes [#3725](https://github.com/vuejs/vue-cli/issues/3725)
|
||||
|
||||
## cli-plugin-babel
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* **generator:** add core-js as direct dependency of generated projects ([#3736](https://github.com/vuejs/vue-cli/issues/3736)) ([5eb1425](https://github.com/vuejs/vue-cli/commit/5eb1425))
|
||||
|
||||
|
||||
|
||||
# [3.5.3](https://github.com/vuejs/vue-cli/compare/v3.5.2...v3.5.3) (2019-03-27)
|
||||
|
||||
## babel-preset-app
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* downgrade [@babel](https://github.com/babel)/preset-env temporarily ([#3716](https://github.com/vuejs/vue-cli/issues/3716)) ([f107623](https://github.com/vuejs/vue-cli/commit/f107623))
|
||||
|
||||
## cli-service
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* properly load non-js config files in genCacheConfig ([#3632](https://github.com/vuejs/vue-cli/issues/3632)) ([adac48d](https://github.com/vuejs/vue-cli/commit/adac48d)), closes [#3631](https://github.com/vuejs/vue-cli/issues/3631)
|
||||
* set the path of safari-no-module-fix.js correctly ([#3647](https://github.com/vuejs/vue-cli/issues/3647)) ([10296ff](https://github.com/vuejs/vue-cli/commit/10296ff)), closes [#3033](https://github.com/vuejs/vue-cli/issues/3033)
|
||||
|
||||
|
||||
|
||||
# [3.5.2](https://github.com/vuejs/vue-cli/compare/v3.5.1...v3.5.2) (2019-03-27)
|
||||
|
||||
## babel-preset-app
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* use absolute import path for injected core-js polyfills ([#3710](https://github.com/vuejs/vue-cli/issues/3710)) ([4d6fcf5](https://github.com/vuejs/vue-cli/commit/4d6fcf5)), closes [#3678](https://github.com/vuejs/vue-cli/issues/3678)
|
||||
* explicitly set corejs version for [@babel](https://github.com/babel)/preset-env ([#3696](https://github.com/vuejs/vue-cli/issues/3696)) ([156ef21](https://github.com/vuejs/vue-cli/commit/156ef21)), closes [#3695](https://github.com/vuejs/vue-cli/issues/3695)
|
||||
|
||||
## docs
|
||||
|
||||
#### Features
|
||||
|
||||
* add manifest.json, make the website installable ([eda048a](https://github.com/vuejs/vue-cli/commit/eda048a))
|
||||
|
||||
|
||||
|
||||
# [3.5.1](https://github.com/vuejs/vue-cli/compare/v3.5.0...v3.5.1) (2019-03-12)
|
||||
|
||||
## cli-service
|
||||
|
||||
@@ -140,14 +140,16 @@ Deprecated since Vue CLI 3.3, please use [`publicPath`](#publicPath) instead.
|
||||
|
||||
### lintOnSave
|
||||
|
||||
- Type: `boolean | 'error'`
|
||||
- Type: `boolean | 'warning' | 'default' | 'error'`
|
||||
- Default: `true`
|
||||
|
||||
Whether to perform lint-on-save during development using [eslint-loader](https://github.com/webpack-contrib/eslint-loader). This value is respected only when [`@vue/cli-plugin-eslint`](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint) is installed.
|
||||
|
||||
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.
|
||||
When set to `true` or `'warning'`, `eslint-loader` will emit lint errors as warnings. By default, warnings are only logged to the terminal and does not fail the compilation, so this is a good default for development.
|
||||
|
||||
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.
|
||||
To make lint errors show up in the browser overlay, you can use `lintOnSave: 'default'`. This will force `eslint-loader` to actually emit errors. this also means lint errors will now cause the compilation to fail.
|
||||
|
||||
Setting it to `'errors'` will force eslint-loader to emit warnings as errors as well, which means warnings will also show up in the overlay.
|
||||
|
||||
Alternatively, you can configure the overlay to display both warnings and errors:
|
||||
|
||||
|
||||
@@ -97,6 +97,14 @@ Add a message to be printed when the generator exits (after any other standard m
|
||||
- **Usage**:
|
||||
Convenience method for generating a JS config file from JSON
|
||||
|
||||
## makeJSOnlyValue
|
||||
|
||||
- **Arguments**
|
||||
- `{any} str` - JS expression as a string
|
||||
|
||||
- **Usage**:
|
||||
Turns a string expression into executable JS for .js config files
|
||||
|
||||
## injectImports
|
||||
|
||||
- **Arguments**
|
||||
|
||||
@@ -13,10 +13,6 @@ App is the default build target. In this mode:
|
||||
|
||||
## Library
|
||||
|
||||
::: tip Note on IE Compatibility
|
||||
In lib mode, the public path is [dynamically determined](https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/commands/build/setPublicPath.js) based on the URL from which the main js file is loaded (to enable dynamic assets loading). However, this feature requires `document.currentScript` support, which is missing in IE. So it's recommended to include the [current-script-polyfill](https://www.npmjs.com/package/current-script-polyfill) in the final web page before the library is imported, if IE support is a requirement.
|
||||
:::
|
||||
|
||||
::: tip Note on Vue Dependency
|
||||
In lib mode, Vue is *externalized*. This means the bundle will not bundle Vue even if your code imports Vue. If the lib is used via a bundler, it will attempt to load Vue as a dependency through the bundler; otherwise, it falls back to a global `Vue` variable.
|
||||
:::
|
||||
|
||||
+9
-1
@@ -12,7 +12,7 @@ You can select pre-processors (Sass/Less/Stylus) when creating the project. If y
|
||||
|
||||
``` bash
|
||||
# Sass
|
||||
npm install -D sass-loader node-sass
|
||||
npm install -D sass-loader sass
|
||||
|
||||
# Less
|
||||
npm install -D less-loader less
|
||||
@@ -29,6 +29,14 @@ $color: red;
|
||||
</style>
|
||||
```
|
||||
|
||||
::: tip A Tip on Sass Performance
|
||||
Note that when using Dart Sass, **synchronous compilation is twice as fast as asynchronous compilation** by default, due to the overhead of asynchronous callbacks. To avoid this overhead, you can use the [fibers](https://www.npmjs.com/package/fibers) package to call asynchronous importers from the synchronous code path. To enable this, simply install `fibers` as a project dependency:
|
||||
```
|
||||
npm install -D fibers
|
||||
```
|
||||
Please also be aware, as it's a native module, there may be compatibility issues vary on the OS and build environment. In that case, please run `npm uninstall -D fibers` to fix the problem.
|
||||
:::
|
||||
|
||||
### Automatic imports
|
||||
|
||||
If you want to automatically import files (for colors, variables, mixins...), you can use the [style-resources-loader](https://github.com/yenshih/style-resources-loader). Here is an example for stylus that imports `./src/styles/imports.styl` in every SFC and every stylus files:
|
||||
|
||||
+15
-2
@@ -1,9 +1,22 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": false,
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"packages": [
|
||||
"packages/@vue/babel-preset-app",
|
||||
"packages/@vue/cli*"
|
||||
]
|
||||
],
|
||||
"changelog": {
|
||||
"repo": "vuejs/vue-cli",
|
||||
"labels": {
|
||||
"PR: New Feature": ":rocket: New Feature",
|
||||
"PR: Breaking Change": ":boom: Breaking Change",
|
||||
"PR: Bug Fix": ":bug: Bug Fix",
|
||||
"PR: Documentation": ":memo: Documentation",
|
||||
"PR: Internal": ":house: Internal",
|
||||
"PR: Underlying Tools": ":hammer: Underlying Tools"
|
||||
},
|
||||
"cacheDir": ".changelog",
|
||||
"nextVersionFromMetadata": true
|
||||
}
|
||||
}
|
||||
|
||||
+12
-16
@@ -14,7 +14,7 @@
|
||||
"sync": "node scripts/syncDeps.js",
|
||||
"boot": "node scripts/bootstrap.js",
|
||||
"release": "yarn --pure-lockfile && yarn clean && node scripts/release.js",
|
||||
"changelog": "node scripts/genChangelog.js run",
|
||||
"version": "node scripts/markVersions.js && node scripts/genChangelog.js && git add packages/vue-cli-version-marker CHANGELOG.md",
|
||||
"docs": "vuepress dev docs",
|
||||
"docs:build": "vuepress build docs",
|
||||
"patch-chromedriver": "node scripts/patchChromedriver.js"
|
||||
@@ -43,46 +43,42 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/conventional-changelog": "^0.1.1",
|
||||
"@vuepress/plugin-pwa": "^1.0.0-alpha.44",
|
||||
"@vuepress/theme-vue": "1.0.0-alpha.44",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"conventional-changelog": "^3.0.6",
|
||||
"debug": "^4.1.0",
|
||||
"eslint": "^5.14.1",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-graphql": "^3.0.3",
|
||||
"eslint-plugin-node": "^8.0.0",
|
||||
"eslint-plugin-vue": "^5.2.2",
|
||||
"eslint-plugin-vue-libs": "^3.0.0",
|
||||
"execa": "^1.0.0",
|
||||
"globby": "^9.0.0",
|
||||
"graphql": "^14.0.2",
|
||||
"globby": "^9.2.0",
|
||||
"graphql": "^14.2.1",
|
||||
"http-server": "^0.11.1",
|
||||
"inquirer": "^6.0.0",
|
||||
"jest": "^23.1.0",
|
||||
"lerna": "^3.13.0",
|
||||
"lint-staged": "^8.1.4",
|
||||
"lerna": "^3.13.2",
|
||||
"lerna-changelog": "^0.8.2",
|
||||
"lint-staged": "^8.1.5",
|
||||
"memfs": "^2.15.2",
|
||||
"minimist": "^1.2.0",
|
||||
"request": "^2.83.0",
|
||||
"request-promise-native": "^1.0.7",
|
||||
"rimraf": "^2.6.2",
|
||||
"semver": "^5.5.0",
|
||||
"typescript": "^3.3.3333",
|
||||
"semver": "^6.0.0",
|
||||
"typescript": "^3.4.3",
|
||||
"vuepress": "1.0.0-alpha.44",
|
||||
"vuepress-theme-vue": "^1.1.0",
|
||||
"webpack": ">=4 < 4.29",
|
||||
"yorkie": "^2.0.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"ps-tree": "^1.1.1",
|
||||
"puppeteer": "1.11.0",
|
||||
"vue": "^2.6.7",
|
||||
"vue-template-compiler": "^2.6.7",
|
||||
"vue-server-renderer": "^2.6.7"
|
||||
"vue": "^2.6.10",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"vue-server-renderer": "^2.6.10"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ Use this option when you have 3rd party dependencies that are not processed by B
|
||||
|
||||
- Default: `true`.
|
||||
|
||||
Set to `false` to disable JSX support.
|
||||
Set to `false` to disable JSX support. Or you can toggle [@vue/babel-preset-jsx](https://github.com/vuejs/jsx/tree/dev/packages/babel-preset-jsx) features here.
|
||||
|
||||
### loose
|
||||
|
||||
|
||||
@@ -7,6 +7,11 @@ const defaultOptions = {
|
||||
filename: 'test-entry-file.js'
|
||||
}
|
||||
|
||||
const genCoreJSImportRegExp = mod => {
|
||||
// expected to include a `node_modules` in the import path because we use absolute path for core-js
|
||||
return new RegExp(`import "${['.*node_modules', 'core-js', 'modules', mod].join(`[\\${path.sep}]+`)}`)
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
process.env.VUE_CLI_ENTRY_FILES = JSON.stringify([path.join(process.cwd(), 'test-entry-file.js')])
|
||||
})
|
||||
@@ -22,9 +27,9 @@ test('polyfill detection', () => {
|
||||
filename: 'test-entry-file.js'
|
||||
})
|
||||
// default includes
|
||||
expect(code).not.toMatch(`import "core-js/modules/es6.promise"`)
|
||||
expect(code).not.toMatch(genCoreJSImportRegExp('es6.promise'))
|
||||
// usage-based detection
|
||||
expect(code).not.toMatch(`import "core-js/modules/es6.map"`)
|
||||
expect(code).not.toMatch(genCoreJSImportRegExp('es6.map'))
|
||||
|
||||
;({ code } = babel.transformSync(`
|
||||
const a = new Map()
|
||||
@@ -36,9 +41,9 @@ test('polyfill detection', () => {
|
||||
filename: 'test-entry-file.js'
|
||||
}))
|
||||
// default includes
|
||||
expect(code).toMatch(`import "core-js/modules/es6.promise"`)
|
||||
expect(code).toMatch(genCoreJSImportRegExp('es6.promise'))
|
||||
// promise polyfill alone doesn't work in IE, needs this as well. fix: #1642
|
||||
expect(code).toMatch(`import "core-js/modules/es6.array.iterator"`)
|
||||
expect(code).toMatch(genCoreJSImportRegExp('es6.array.iterator'))
|
||||
// usage-based detection
|
||||
expect(code).toMatch(/import _Map from ".*runtime-corejs2\/core-js\/map"/)
|
||||
})
|
||||
@@ -56,7 +61,7 @@ test('modern mode always skips polyfills', () => {
|
||||
filename: 'test-entry-file.js'
|
||||
})
|
||||
// default includes
|
||||
expect(code).not.toMatch(`import "core-js/modules/es6.promise"`)
|
||||
expect(code).not.toMatch(genCoreJSImportRegExp('es6.promise'))
|
||||
// usage-based detection
|
||||
expect(code).not.toMatch(/import _Map from ".*runtime-corejs2\/core-js\/map"/)
|
||||
|
||||
@@ -71,7 +76,7 @@ test('modern mode always skips polyfills', () => {
|
||||
filename: 'test-entry-file.js'
|
||||
}))
|
||||
// default includes
|
||||
expect(code).not.toMatch(`import "core-js/modules/es6.promise"`)
|
||||
expect(code).not.toMatch(genCoreJSImportRegExp('es6.promise'))
|
||||
// usage-based detection
|
||||
expect(code).not.toMatch(/import _Map from ".*runtime-corejs2\/core-js\/map"/)
|
||||
delete process.env.VUE_CLI_MODERN_BUILD
|
||||
@@ -98,7 +103,7 @@ test('async/await', () => {
|
||||
}
|
||||
hello()
|
||||
`.trim(), defaultOptions)
|
||||
expect(code).toMatch(`import "core-js/modules/es6.promise"`)
|
||||
expect(code).toMatch(genCoreJSImportRegExp('es6.promise'))
|
||||
// should use regenerator runtime
|
||||
expect(code).toMatch(`import "regenerator-runtime/runtime"`)
|
||||
// should use required helper instead of inline
|
||||
@@ -148,4 +153,5 @@ test('disable absoluteRuntime', () => {
|
||||
})
|
||||
|
||||
expect(code).toMatch('import _toConsumableArray from "@babel/runtime-corejs2/helpers/esm/toConsumableArray"')
|
||||
// expect(code).not.toMatch(genCoreJSImportRegExp('es6.promise'))
|
||||
})
|
||||
|
||||
@@ -106,7 +106,10 @@ module.exports = (context, options = {}) => {
|
||||
ignoreBrowserslistConfig,
|
||||
configPath
|
||||
})
|
||||
plugins.push([require('./polyfillsPlugin'), { polyfills, entryFiles }])
|
||||
plugins.push([
|
||||
require('./polyfillsPlugin'),
|
||||
{ polyfills, entryFiles, useAbsolutePath: !!absoluteRuntime }
|
||||
])
|
||||
} else {
|
||||
polyfills = []
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/babel-preset-app",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "babel-preset-app for vue-cli",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
@@ -22,16 +22,18 @@
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/babel-preset-app#readme",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.0.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.0.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.1.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||
"@babel/plugin-syntax-jsx": "^7.0.0",
|
||||
"@babel/plugin-transform-runtime": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/plugin-transform-runtime": "^7.4.0",
|
||||
"@babel/preset-env": "^7.0.0 < 7.4.0",
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"@babel/runtime-corejs2": "^7.2.0",
|
||||
"@vue/babel-preset-jsx": "^1.0.0-beta.2",
|
||||
"@vue/babel-preset-jsx": "^1.0.0-beta.3",
|
||||
"babel-plugin-dynamic-import-node": "^2.2.0",
|
||||
"core-js": "^2.6.5"
|
||||
}
|
||||
},
|
||||
"gitHead": "0dc793497281718762a5477a3de4a7ee439cdda6"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
const { addSideEffect } = require('@babel/helper-module-imports')
|
||||
|
||||
// slightly modifiled from @babel/preset-env/src/utils
|
||||
// use an absolute path for core-js modules, to fix conflicts of different core-js versions
|
||||
function getModulePath (mod, useAbsolutePath) {
|
||||
const modPath =
|
||||
mod === 'regenerator-runtime'
|
||||
? 'regenerator-runtime/runtime'
|
||||
: `core-js/modules/${mod}`
|
||||
return useAbsolutePath ? require.resolve(modPath) : modPath
|
||||
}
|
||||
|
||||
function createImport (path, mod, useAbsolutePath) {
|
||||
return addSideEffect(path, getModulePath(mod, useAbsolutePath))
|
||||
}
|
||||
|
||||
// add polyfill imports to the first file encountered.
|
||||
module.exports = ({ types }, { entryFiles = [] }) => {
|
||||
module.exports = (
|
||||
{ types },
|
||||
{ polyfills, entryFiles = [], useAbsolutePath }
|
||||
) => {
|
||||
return {
|
||||
name: 'vue-cli-inject-polyfills',
|
||||
visitor: {
|
||||
@@ -8,12 +27,13 @@ module.exports = ({ types }, { entryFiles = [] }) => {
|
||||
return
|
||||
}
|
||||
|
||||
const { polyfills } = state.opts
|
||||
const { createImport } = require('@babel/preset-env/lib/utils')
|
||||
// imports are injected in reverse order
|
||||
polyfills.slice().reverse().forEach(p => {
|
||||
createImport(path, p)
|
||||
})
|
||||
polyfills
|
||||
.slice()
|
||||
.reverse()
|
||||
.forEach(p => {
|
||||
createImport(path, p, useAbsolutePath)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-init",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "init addon for vue-cli",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-overlay",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "error overlay & dev server middleware for vue-cli",
|
||||
"main": "dist/client.js",
|
||||
"files": [
|
||||
|
||||
@@ -8,6 +8,9 @@ module.exports = api => {
|
||||
api.extendPackage({
|
||||
babel: {
|
||||
presets: ['@vue/app']
|
||||
},
|
||||
dependencies: {
|
||||
'core-js': '^2.6.5'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-babel",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "babel plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -21,12 +21,13 @@
|
||||
"homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-babel#readme",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.0.0",
|
||||
"@vue/babel-preset-app": "^3.5.1",
|
||||
"@vue/cli-shared-utils": "^3.5.1",
|
||||
"@vue/babel-preset-app": "^3.6.0",
|
||||
"@vue/cli-shared-utils": "^3.6.0",
|
||||
"babel-loader": "^8.0.5",
|
||||
"webpack": ">=4 < 4.29"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
},
|
||||
"gitHead": "0dc793497281718762a5477a3de4a7ee439cdda6"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-e2e-cypress",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "e2e-cypress plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -23,8 +23,8 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/cli-shared-utils": "^3.5.1",
|
||||
"cypress": "^3.1.5",
|
||||
"@vue/cli-shared-utils": "^3.6.0",
|
||||
"cypress": "^3.2.0",
|
||||
"eslint-plugin-cypress": "^2.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-e2e-nightwatch",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "e2e-nightwatch plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -23,7 +23,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/cli-shared-utils": "^3.5.1",
|
||||
"@vue/cli-shared-utils": "^3.6.0",
|
||||
"chromedriver": "^2.46.0",
|
||||
"deepmerge": "^3.2.0",
|
||||
"execa": "^1.0.0",
|
||||
|
||||
@@ -19,7 +19,7 @@ module.exports = (api, { config, lintOn = [] }, _, invoking) => {
|
||||
// in order to keep compatibility with v3.0.x users who defaults to ESlint v4.
|
||||
devDependencies: {
|
||||
'babel-eslint': '^10.0.1',
|
||||
'eslint': '^5.8.0',
|
||||
'eslint': '^5.16.0',
|
||||
'eslint-plugin-vue': '^5.0.0'
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ module.exports = (api, { config, lintOn = [] }, _, invoking) => {
|
||||
|
||||
if (lintOn.includes('commit')) {
|
||||
Object.assign(pkg.devDependencies, {
|
||||
'lint-staged': '^8.1.4'
|
||||
'lint-staged': '^8.1.5'
|
||||
})
|
||||
pkg.gitHooks = {
|
||||
'pre-commit': 'lint-staged'
|
||||
|
||||
@@ -17,7 +17,7 @@ module.exports = (api, options) => {
|
||||
'eslint-loader',
|
||||
{
|
||||
'eslint-loader': require('eslint-loader/package.json').version,
|
||||
'eslint': eslintPkg.version
|
||||
eslint: eslintPkg.version
|
||||
},
|
||||
[
|
||||
'.eslintrc.js',
|
||||
@@ -30,7 +30,13 @@ module.exports = (api, options) => {
|
||||
)
|
||||
|
||||
api.chainWebpack(webpackConfig => {
|
||||
webpackConfig.resolveLoader.modules.prepend(path.join(__dirname, 'node_modules'))
|
||||
webpackConfig.resolveLoader.modules.prepend(
|
||||
path.join(__dirname, 'node_modules')
|
||||
)
|
||||
|
||||
const { lintOnSave } = options
|
||||
const allWarnings = lintOnSave === true || lintOnSave === 'warning'
|
||||
const allErrors = lintOnSave === 'error'
|
||||
|
||||
webpackConfig.module
|
||||
.rule('eslint')
|
||||
@@ -46,8 +52,9 @@ module.exports = (api, options) => {
|
||||
extensions,
|
||||
cache: true,
|
||||
cacheIdentifier,
|
||||
emitWarning: options.lintOnSave !== 'error',
|
||||
emitError: options.lintOnSave === 'error',
|
||||
emitWarning: allWarnings,
|
||||
// only emit errors in production mode.
|
||||
emitError: allErrors,
|
||||
eslintPath: resolveModule('eslint', cwd) || require.resolve('eslint'),
|
||||
formatter:
|
||||
loadModule('eslint/lib/formatters/codeframe', cwd, true) ||
|
||||
@@ -56,18 +63,25 @@ module.exports = (api, options) => {
|
||||
})
|
||||
}
|
||||
|
||||
api.registerCommand('lint', {
|
||||
description: 'lint and fix source files',
|
||||
usage: 'vue-cli-service lint [options] [...files]',
|
||||
options: {
|
||||
'--format [formatter]': 'specify formatter (default: codeframe)',
|
||||
'--no-fix': 'do not fix errors or warnings',
|
||||
'--no-fix-warnings': 'fix errors, but do not fix warnings',
|
||||
'--max-errors [limit]': 'specify number of errors to make build failed (default: 0)',
|
||||
'--max-warnings [limit]': 'specify number of warnings to make build failed (default: Infinity)'
|
||||
api.registerCommand(
|
||||
'lint',
|
||||
{
|
||||
description: 'lint and fix source files',
|
||||
usage: 'vue-cli-service lint [options] [...files]',
|
||||
options: {
|
||||
'--format [formatter]': 'specify formatter (default: codeframe)',
|
||||
'--no-fix': 'do not fix errors or warnings',
|
||||
'--no-fix-warnings': 'fix errors, but do not fix warnings',
|
||||
'--max-errors [limit]':
|
||||
'specify number of errors to make build failed (default: 0)',
|
||||
'--max-warnings [limit]':
|
||||
'specify number of warnings to make build failed (default: Infinity)'
|
||||
},
|
||||
details:
|
||||
'For more options, see https://eslint.org/docs/user-guide/command-line-interface#options'
|
||||
},
|
||||
details: 'For more options, see https://eslint.org/docs/user-guide/command-line-interface#options'
|
||||
}, args => {
|
||||
require('./lint')(args, api)
|
||||
})
|
||||
args => {
|
||||
require('./lint')(args, api)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-eslint",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "eslint plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -23,10 +23,10 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/cli-shared-utils": "^3.5.1",
|
||||
"@vue/cli-shared-utils": "^3.6.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"eslint-loader": "^2.1.2",
|
||||
"globby": "^9.0.0",
|
||||
"globby": "^9.2.0",
|
||||
"webpack": ">=4 < 4.29"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-pwa",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "pwa plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -23,7 +23,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/cli-shared-utils": "^3.5.1",
|
||||
"@vue/cli-shared-utils": "^3.6.0",
|
||||
"webpack": ">=4 < 4.29",
|
||||
"workbox-webpack-plugin": "^3.6.3"
|
||||
},
|
||||
|
||||
@@ -9,15 +9,15 @@ module.exports = (api, {
|
||||
|
||||
api.extendPackage({
|
||||
devDependencies: {
|
||||
typescript: '^3.2.1'
|
||||
typescript: '^3.4.3'
|
||||
}
|
||||
})
|
||||
|
||||
if (classComponent) {
|
||||
api.extendPackage({
|
||||
dependencies: {
|
||||
'vue-class-component': '^6.0.0',
|
||||
'vue-property-decorator': '^8.0.0'
|
||||
'vue-class-component': '^7.0.2',
|
||||
'vue-property-decorator': '^8.1.0'
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -40,7 +40,7 @@ module.exports = (api, {
|
||||
if (lintOn.includes('commit')) {
|
||||
api.extendPackage({
|
||||
devDependencies: {
|
||||
'lint-staged': '^8.1.0'
|
||||
'lint-staged': '^8.1.5'
|
||||
},
|
||||
gitHooks: {
|
||||
'pre-commit': 'lint-staged'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-typescript",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "typescript plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -23,12 +23,12 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/webpack-env": "^1.13.6",
|
||||
"@vue/cli-shared-utils": "^3.5.1",
|
||||
"@types/webpack-env": "^1.13.9",
|
||||
"@vue/cli-shared-utils": "^3.6.0",
|
||||
"fork-ts-checker-webpack-plugin": "^0.5.2",
|
||||
"globby": "^9.0.0",
|
||||
"globby": "^9.2.0",
|
||||
"ts-loader": "^5.3.3",
|
||||
"tslint": "^5.13.0",
|
||||
"tslint": "^5.15.0",
|
||||
"webpack": ">=4 < 4.29"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -38,8 +38,9 @@
|
||||
"@types/chai": "^4.1.0",
|
||||
"@types/jest": "^23.1.4",
|
||||
"@types/mocha": "^5.2.6",
|
||||
"typescript": "^3.2.1",
|
||||
"vue-class-component": "^7.0.1",
|
||||
"vue-property-decorator": "^8.0.0"
|
||||
}
|
||||
"typescript": "^3.4.3",
|
||||
"vue-class-component": "^7.0.2",
|
||||
"vue-property-decorator": "^8.1.0"
|
||||
},
|
||||
"gitHead": "0dc793497281718762a5477a3de4a7ee439cdda6"
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ vue add @vue/unit-jest
|
||||
|
||||
## Transform dependencies from `/node_modules`
|
||||
|
||||
By default, jest doesn't transform anything from `/nodee_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.
|
||||
|
||||
|
||||
@@ -11,32 +11,35 @@ module.exports = (api, _, __, invoking) => {
|
||||
'@vue/test-utils': '1.0.0-beta.29'
|
||||
},
|
||||
jest: {
|
||||
'moduleFileExtensions': [
|
||||
moduleFileExtensions: [
|
||||
'js',
|
||||
'jsx',
|
||||
'json',
|
||||
// tell Jest to handle *.vue files
|
||||
'vue'
|
||||
],
|
||||
'transform': {
|
||||
transform: {
|
||||
// process *.vue files with vue-jest
|
||||
'^.+\\.vue$': 'vue-jest',
|
||||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub'
|
||||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
|
||||
'jest-transform-stub'
|
||||
},
|
||||
'transformIgnorePatterns': ['/node_modules/'],
|
||||
// support the same @ -> src alias mapping in source code
|
||||
'moduleNameMapper': {
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$': '<rootDir>/src/$1'
|
||||
},
|
||||
// serializer for snapshots
|
||||
'snapshotSerializers': [
|
||||
'jest-serializer-vue'
|
||||
],
|
||||
'testMatch': [
|
||||
snapshotSerializers: ['jest-serializer-vue'],
|
||||
testMatch: [
|
||||
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
|
||||
],
|
||||
// https://github.com/facebook/jest/issues/6766
|
||||
'testURL': 'http://localhost/'
|
||||
testURL: 'http://localhost/',
|
||||
watchPlugins: [
|
||||
require.resolve('jest-watch-typeahead/filename'),
|
||||
require.resolve('jest-watch-typeahead/testname')
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
@@ -60,9 +63,13 @@ module.exports = (api, _, __, invoking) => {
|
||||
// Jest's shipped babel-jest still uses babel 6,
|
||||
// so we cannot use extendPackage which renders babel.config.js.
|
||||
api.render(files => {
|
||||
files['.babelrc'] = JSON.stringify({
|
||||
plugins: ['transform-es2015-modules-commonjs']
|
||||
}, null, 2)
|
||||
files['.babelrc'] = JSON.stringify(
|
||||
{
|
||||
plugins: ['transform-es2015-modules-commonjs']
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@@ -74,7 +81,7 @@ module.exports = (api, _, __, invoking) => {
|
||||
}
|
||||
}
|
||||
|
||||
const applyTS = module.exports.applyTS = (api, invoking) => {
|
||||
const applyTS = (module.exports.applyTS = (api, invoking) => {
|
||||
api.extendPackage({
|
||||
jest: {
|
||||
moduleFileExtensions: ['ts', 'tsx'],
|
||||
@@ -119,12 +126,12 @@ const applyTS = module.exports.applyTS = (api, invoking) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const applyESLint = module.exports.applyESLint = api => {
|
||||
const applyESLint = (module.exports.applyESLint = api => {
|
||||
api.render(files => {
|
||||
files['tests/unit/.eslintrc.js'] = api.genJSConfig({
|
||||
env: { jest: true }
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-unit-jest",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "unit-jest plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -23,16 +23,18 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/cli-shared-utils": "^3.5.1",
|
||||
"@vue/cli-shared-utils": "^3.6.0",
|
||||
"babel-jest": "^23.6.0",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
|
||||
"jest": "^23.6.0",
|
||||
"jest-serializer-vue": "^2.0.2",
|
||||
"jest-transform-stub": "^2.0.0",
|
||||
"vue-jest": "^3.0.3"
|
||||
"jest-watch-typeahead": "^0.3.0",
|
||||
"vue-jest": "^3.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"ts-jest": "^23.0.0"
|
||||
}
|
||||
},
|
||||
"gitHead": "0dc793497281718762a5477a3de4a7ee439cdda6"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-unit-mocha",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "mocha unit testing plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-unit-mocha#readme",
|
||||
"dependencies": {
|
||||
"@vue/cli-shared-utils": "^3.5.1",
|
||||
"@vue/cli-shared-utils": "^3.6.0",
|
||||
"jsdom": "^13.2.0",
|
||||
"jsdom-global": "^3.0.2",
|
||||
"mocha": "^5.2.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-service-global",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "vue-cli-service global addon for vue-cli",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
@@ -22,16 +22,17 @@
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-build#readme",
|
||||
"dependencies": {
|
||||
"@vue/babel-preset-app": "^3.5.1",
|
||||
"@vue/cli-plugin-babel": "^3.5.1",
|
||||
"@vue/cli-plugin-eslint": "^3.5.1",
|
||||
"@vue/cli-service": "^3.5.1",
|
||||
"@vue/babel-preset-app": "^3.6.0",
|
||||
"@vue/cli-plugin-babel": "^3.6.0",
|
||||
"@vue/cli-plugin-eslint": "^3.6.0",
|
||||
"@vue/cli-service": "^3.6.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"chalk": "^2.4.2",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-plugin-vue": "^4.7.1",
|
||||
"resolve": "^1.10.0",
|
||||
"vue": "^2.6.6",
|
||||
"vue-template-compiler": "^2.6.6"
|
||||
}
|
||||
"vue": "^2.6.10",
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
},
|
||||
"gitHead": "0dc793497281718762a5477a3de4a7ee439cdda6"
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ test('loading plugins from package.json', () => {
|
||||
mockPkg({
|
||||
devDependencies: {
|
||||
'bar': '^1.0.0',
|
||||
'@vue/cli-plugin-babel': '^3.5.0',
|
||||
'@vue/cli-plugin-babel': '^3.6.0',
|
||||
'vue-cli-plugin-foo': '^1.0.0'
|
||||
}
|
||||
})
|
||||
@@ -253,7 +253,6 @@ test('api: configureWebpack', () => {
|
||||
}])
|
||||
|
||||
const config = service.resolveWebpackConfig()
|
||||
console.log(process.env.VUE_CLI_ENTRY_FILES)
|
||||
expect(config.output.path).toBe('test-dist-2')
|
||||
})
|
||||
|
||||
|
||||
@@ -132,3 +132,45 @@ test('build as lib with webpackConfiguration depending on target (js)', async ()
|
||||
const commonContent = await project.read('dist/testLib.common.js')
|
||||
expect(commonContent).not.toContain(`foo: 'bar'`)
|
||||
})
|
||||
|
||||
test('build as lib with --filename option', async () => {
|
||||
const project = await create('build-lib-filename-option', defaultPreset)
|
||||
await project.write('src/main.js', `
|
||||
export default { foo: 1 }
|
||||
export const bar = 2
|
||||
`)
|
||||
const { stdout } = await project.run('vue-cli-service build --target lib --name testLib --filename test-lib src/main.js')
|
||||
expect(stdout).toMatch('Build complete.')
|
||||
|
||||
expect(project.has('dist/demo.html')).toBe(true)
|
||||
expect(project.has('dist/test-lib.common.js')).toBe(true)
|
||||
expect(project.has('dist/test-lib.umd.js')).toBe(true)
|
||||
expect(project.has('dist/test-lib.umd.min.js')).toBe(true)
|
||||
|
||||
const port = await portfinder.getPortPromise()
|
||||
server = createServer({ root: path.join(project.dir, 'dist') })
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
server.listen(port, err => {
|
||||
if (err) return reject(err)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
const launched = await launchPuppeteer(`http://localhost:${port}/demo.html`)
|
||||
browser = launched.browser
|
||||
page = launched.page
|
||||
|
||||
expect(await page.evaluate(() => {
|
||||
return window.document.title
|
||||
})).toBe('testLib demo')
|
||||
|
||||
// should expose a module with default and named exports
|
||||
expect(await page.evaluate(() => {
|
||||
return window.testLib.default.foo
|
||||
})).toBe(1)
|
||||
|
||||
expect(await page.evaluate(() => {
|
||||
return window.testLib.bar
|
||||
})).toBe(2)
|
||||
})
|
||||
|
||||
@@ -43,5 +43,4 @@ test('dart sass', async () => {
|
||||
|
||||
expect(files['src/App.vue']).toMatch('<style lang="scss">')
|
||||
expect(pkg).toHaveProperty(['devDependencies', 'sass'])
|
||||
expect(pkg).toHaveProperty(['devDependencies', 'fibers'])
|
||||
})
|
||||
|
||||
@@ -15,7 +15,7 @@ async function makeProjectMultiPage (project) {
|
||||
index: { entry: 'src/main.js' },
|
||||
foo: { entry: 'src/foo.js' },
|
||||
bar: { entry: 'src/bar.js' },
|
||||
foobar: { entry: 'src/foobar.js' }
|
||||
foobar: { entry: ['src/foobar.js'] }
|
||||
},
|
||||
chainWebpack: config => {
|
||||
const splitOptions = config.optimization.get('splitChunks')
|
||||
|
||||
@@ -9,7 +9,7 @@ module.exports = (api, options) => {
|
||||
'build': 'vue-cli-service build'
|
||||
},
|
||||
dependencies: {
|
||||
'vue': '^2.6.6'
|
||||
'vue': '^2.6.10'
|
||||
},
|
||||
devDependencies: {
|
||||
'vue-template-compiler': '^2.5.21'
|
||||
@@ -46,8 +46,7 @@ module.exports = (api, options) => {
|
||||
'sass-loader': '^7.1.0'
|
||||
},
|
||||
'dart-sass': {
|
||||
fibers: '^3.1.1',
|
||||
sass: '^1.17.2',
|
||||
sass: '^1.18.0',
|
||||
'sass-loader': '^7.1.0'
|
||||
},
|
||||
less: {
|
||||
|
||||
@@ -3,7 +3,7 @@ module.exports = (api, options = {}) => {
|
||||
api.injectRootOptions(api.entryFile, `router`)
|
||||
api.extendPackage({
|
||||
dependencies: {
|
||||
'vue-router': '^3.0.1'
|
||||
'vue-router': '^3.0.3'
|
||||
}
|
||||
})
|
||||
api.render('./template', {
|
||||
|
||||
@@ -28,4 +28,4 @@ yarn-error.log*
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw*
|
||||
*.sw?
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 4.2 KiB |
@@ -166,6 +166,8 @@ class PluginAPI {
|
||||
} catch (e) {
|
||||
return fs.readFileSync(absolutePath, 'utf-8')
|
||||
}
|
||||
} else {
|
||||
return fs.readFileSync(absolutePath, 'utf-8')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<meta charset="utf-8">
|
||||
<title><%- htmlWebpackPlugin.options.libName %> demo</title>
|
||||
<script src="./<%- htmlWebpackPlugin.options.libName %>.umd.js"></script>
|
||||
<script src="./<%- htmlWebpackPlugin.options.assetsFileName %>.umd.js"></script>
|
||||
<% if (htmlWebpackPlugin.options.cssExtract) { %>
|
||||
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.libName %>.css">
|
||||
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.assetsFileName %>.css">
|
||||
<% } %>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<meta charset="utf-8">
|
||||
<title><%- htmlWebpackPlugin.options.libName %> demo</title>
|
||||
<script src="https://unpkg.com/vue"></script>
|
||||
<script src="./<%- htmlWebpackPlugin.options.libName %>.umd.js"></script>
|
||||
<script src="./<%- htmlWebpackPlugin.options.assetsFileName %>.umd.js"></script>
|
||||
<% if (htmlWebpackPlugin.options.cssExtract) { %>
|
||||
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.libName %>.css">
|
||||
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.assetsFileName %>.css">
|
||||
<% } %>
|
||||
|
||||
<div id="app">
|
||||
|
||||
@@ -31,6 +31,7 @@ module.exports = (api, options) => {
|
||||
'--target': `app | lib | wc | wc-async (default: ${defaults.target})`,
|
||||
'--formats': `list of output formats for library builds (default: ${defaults.formats})`,
|
||||
'--name': `name for lib or web-component mode (default: "name" in package.json or entry filename)`,
|
||||
'--filename': `file name for output, only usable for 'lib' target (default: value of --name)`,
|
||||
'--no-clean': `do not remove the dist directory before building the project`,
|
||||
'--report': `generate report.html to help analyze bundle content`,
|
||||
'--report-json': 'generate report.json to help analyze bundle content',
|
||||
|
||||
@@ -28,7 +28,10 @@ module.exports = (api, args, options) => {
|
||||
.use(ModernModePlugin, [{
|
||||
targetDir,
|
||||
isModernBuild: true,
|
||||
unsafeInline: args['unsafe-inline']
|
||||
unsafeInline: args['unsafe-inline'],
|
||||
// as we may generate an addition file asset (if `no-unsafe-inline` specified)
|
||||
// we need to provide the correct directory for that file to place in
|
||||
jsDirectory: require('../../util/getAssetPath')(options, 'js')
|
||||
}])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = (api, { entry, name, formats }, options) => {
|
||||
module.exports = (api, { entry, name, formats, filename }, options) => {
|
||||
const { log, error } = require('@vue/cli-shared-utils')
|
||||
const abort = msg => {
|
||||
log()
|
||||
@@ -24,16 +24,26 @@ module.exports = (api, { entry, name, formats }, options) => {
|
||||
api.service.pkg.name ||
|
||||
path.basename(entry).replace(/\.(jsx?|vue)$/, '')
|
||||
)
|
||||
|
||||
filename = filename || libName
|
||||
function genConfig (format, postfix = format, genHTML) {
|
||||
const config = api.resolveChainableWebpackConfig()
|
||||
|
||||
const browserslist = require('browserslist')
|
||||
const targets = browserslist(undefined, { path: fullEntryPath })
|
||||
const supportsIE = targets.some(agent => agent.includes('ie'))
|
||||
|
||||
const webpack = require('webpack')
|
||||
config.plugin('need-current-script-polyfill')
|
||||
.use(webpack.DefinePlugin, [{
|
||||
'process.env.NEED_CURRENTSCRIPT_POLYFILL': JSON.stringify(supportsIE)
|
||||
}])
|
||||
|
||||
// adjust css output name so they write to the same file
|
||||
if (config.plugins.has('extract-css')) {
|
||||
config
|
||||
.plugin('extract-css')
|
||||
.tap(args => {
|
||||
args[0].filename = `${libName}.css`
|
||||
args[0].filename = `${filename}.css`
|
||||
return args
|
||||
})
|
||||
}
|
||||
@@ -64,12 +74,13 @@ module.exports = (api, { entry, name, formats }, options) => {
|
||||
inject: false,
|
||||
filename: 'demo.html',
|
||||
libName,
|
||||
assetsFileName: filename,
|
||||
cssExtract: config.plugins.has('extract-css')
|
||||
}])
|
||||
}
|
||||
|
||||
// resolve entry/output
|
||||
const entryName = `${libName}.${postfix}`
|
||||
const entryName = `${filename}.${postfix}`
|
||||
config.resolve
|
||||
.alias
|
||||
.set('~entry', fullEntryPath)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
// This file is imported into lib/wc client bundles.
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
if (process.env.NEED_CURRENTSCRIPT_POLYFILL) {
|
||||
require('current-script-polyfill')
|
||||
}
|
||||
|
||||
var i
|
||||
if ((i = window.document.currentScript) && (i = i.src.match(/(.+\/)[^/]+\.js(\?.*)?$/))) {
|
||||
__webpack_public_path__ = i[1] // eslint-disable-line
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const {
|
||||
info,
|
||||
hasProjectYarn,
|
||||
hasProjectPnpm,
|
||||
openBrowser,
|
||||
IpcMessenger
|
||||
} = require('@vue/cli-shared-utils')
|
||||
@@ -234,7 +235,7 @@ module.exports = (api, options) => {
|
||||
isFirstCompile = false
|
||||
|
||||
if (!isProduction) {
|
||||
const buildCommand = hasProjectYarn(api.getCwd()) ? `yarn build` : `npm run build`
|
||||
const buildCommand = hasProjectYarn(api.getCwd()) ? `yarn build` : hasProjectPnpm(api.getCwd()) ? `pnpm run build` : `npm run build`
|
||||
console.log(` Note that the development build is not optimized.`)
|
||||
console.log(` To create a production build, run ${chalk.cyan(buildCommand)}.`)
|
||||
} else {
|
||||
|
||||
@@ -199,7 +199,8 @@ module.exports = (api, options) => {
|
||||
}
|
||||
|
||||
// inject entry
|
||||
webpackConfig.entry(name).add(api.resolve(entry))
|
||||
const entries = Array.isArray(entry) ? entry : [entry]
|
||||
webpackConfig.entry(name).merge(entries.map(e => api.resolve(e)))
|
||||
|
||||
// resolve page index template
|
||||
const hasDedicatedTemplate = fs.existsSync(api.resolve(template))
|
||||
|
||||
@@ -130,10 +130,21 @@ module.exports = (api, options) => {
|
||||
|
||||
webpackConfig.module
|
||||
.rule('pug')
|
||||
.test(/\.pug$/)
|
||||
.use('pug-plain-loader')
|
||||
.loader('pug-plain-loader')
|
||||
.end()
|
||||
.test(/\.pug$/)
|
||||
.oneOf('pug-vue')
|
||||
.resourceQuery(/vue/)
|
||||
.use('pug-plain-loader')
|
||||
.loader('pug-plain-loader')
|
||||
.end()
|
||||
.end()
|
||||
.oneOf('pug-template')
|
||||
.use('raw')
|
||||
.loader('raw-loader')
|
||||
.end()
|
||||
.use('pug-plain')
|
||||
.loader('pug-plain-loader')
|
||||
.end()
|
||||
.end()
|
||||
|
||||
// shims
|
||||
|
||||
|
||||
@@ -15,9 +15,14 @@ const schema = createSchema(joi => joi.object({
|
||||
pages: joi.object().pattern(
|
||||
/\w+/,
|
||||
joi.alternatives().try([
|
||||
joi.string(),
|
||||
joi.string().required(),
|
||||
joi.array().items(joi.string().required()),
|
||||
|
||||
joi.object().keys({
|
||||
entry: joi.string().required()
|
||||
entry: joi.alternatives().try([
|
||||
joi.string().required(),
|
||||
joi.array().items(joi.string().required())
|
||||
]).required()
|
||||
}).unknown(true)
|
||||
])
|
||||
),
|
||||
@@ -46,7 +51,7 @@ const schema = createSchema(joi => joi.object({
|
||||
),
|
||||
|
||||
// known runtime options for built-in plugins
|
||||
lintOnSave: joi.any().valid([true, false, 'error']),
|
||||
lintOnSave: joi.any().valid([true, false, 'error', 'warning', 'default']),
|
||||
pwa: joi.object(),
|
||||
|
||||
// 3rd party plugin options
|
||||
@@ -90,7 +95,9 @@ exports.defaults = () => ({
|
||||
runtimeCompiler: false,
|
||||
|
||||
// deps to transpile
|
||||
transpileDependencies: [/* string or regex */],
|
||||
transpileDependencies: [
|
||||
/* string or regex */
|
||||
],
|
||||
|
||||
// sourceMap for production build?
|
||||
productionSourceMap: !process.env.VUE_CLI_TEST,
|
||||
@@ -121,7 +128,7 @@ exports.defaults = () => ({
|
||||
lintOnSave: true,
|
||||
|
||||
devServer: {
|
||||
/*
|
||||
/*
|
||||
open: process.platform === 'darwin',
|
||||
host: '0.0.0.0',
|
||||
port: 8080,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const path = require('path')
|
||||
|
||||
module.exports = function getAssetPath (options, filePath, placeAtRootIfRelative) {
|
||||
module.exports = function getAssetPath (options, filePath) {
|
||||
return options.assetsDir
|
||||
? path.posix.join(options.assetsDir, filePath)
|
||||
: filePath
|
||||
|
||||
@@ -5,10 +5,11 @@ const path = require('path')
|
||||
const safariFix = `!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()},!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();`
|
||||
|
||||
class ModernModePlugin {
|
||||
constructor ({ targetDir, isModernBuild, unsafeInline }) {
|
||||
constructor ({ targetDir, isModernBuild, unsafeInline, jsDirectory }) {
|
||||
this.targetDir = targetDir
|
||||
this.isModernBuild = isModernBuild
|
||||
this.unsafeInline = unsafeInline
|
||||
this.jsDirectory = jsDirectory
|
||||
}
|
||||
|
||||
apply (compiler) {
|
||||
@@ -75,11 +76,8 @@ class ModernModePlugin {
|
||||
})
|
||||
} else {
|
||||
// inject the fix as an external script
|
||||
const safariFixPath = legacyAssets[0].attributes.src
|
||||
.split('/')
|
||||
.slice(0, -1)
|
||||
.concat(['safari-nomodule-fix.js'])
|
||||
.join('/')
|
||||
const safariFixPath = path.join(this.jsDirectory, 'safari-nomodule-fix.js')
|
||||
const fullSafariFixPath = path.join(compilation.options.output.publicPath, safariFixPath)
|
||||
compilation.assets[safariFixPath] = {
|
||||
source: function () {
|
||||
return new Buffer(safariFix)
|
||||
@@ -92,7 +90,7 @@ class ModernModePlugin {
|
||||
tagName: 'script',
|
||||
closeTag: true,
|
||||
attributes: {
|
||||
src: safariFixPath
|
||||
src: fullSafariFixPath
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-service",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "local service for vue-cli projects",
|
||||
"main": "lib/Service.js",
|
||||
"typings": "types/index.d.ts",
|
||||
@@ -25,55 +25,57 @@
|
||||
"dependencies": {
|
||||
"@intervolga/optimize-cssnano-plugin": "^1.0.5",
|
||||
"@soda/friendly-errors-webpack-plugin": "^1.7.1",
|
||||
"@vue/cli-overlay": "^3.5.1",
|
||||
"@vue/cli-shared-utils": "^3.5.1",
|
||||
"@vue/cli-overlay": "^3.6.0",
|
||||
"@vue/cli-shared-utils": "^3.6.0",
|
||||
"@vue/component-compiler-utils": "^2.6.0",
|
||||
"@vue/preload-webpack-plugin": "^1.1.0",
|
||||
"@vue/web-component-wrapper": "^1.2.0",
|
||||
"acorn": "^6.1.0",
|
||||
"acorn": "^6.1.1",
|
||||
"acorn-walk": "^6.1.1",
|
||||
"address": "^1.0.3",
|
||||
"autoprefixer": "^9.4.8",
|
||||
"autoprefixer": "^9.5.1",
|
||||
"browserslist": "^4.5.4",
|
||||
"cache-loader": "^2.0.1",
|
||||
"case-sensitive-paths-webpack-plugin": "^2.2.0",
|
||||
"chalk": "^2.4.2",
|
||||
"clipboardy": "^1.2.3",
|
||||
"cliui": "^4.1.0",
|
||||
"clipboardy": "^2.0.0",
|
||||
"cliui": "^5.0.0",
|
||||
"copy-webpack-plugin": "^4.6.0",
|
||||
"css-loader": "^1.0.1",
|
||||
"cssnano": "^4.1.10",
|
||||
"current-script-polyfill": "^1.0.0",
|
||||
"debug": "^4.1.1",
|
||||
"dotenv": "^6.2.0",
|
||||
"dotenv-expand": "^4.2.0",
|
||||
"dotenv": "^7.0.0",
|
||||
"dotenv-expand": "^5.1.0",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"file-loader": "^3.0.1",
|
||||
"fs-extra": "^7.0.1",
|
||||
"globby": "^9.0.0",
|
||||
"globby": "^9.2.0",
|
||||
"hash-sum": "^1.0.2",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"launch-editor-middleware": "^2.2.1",
|
||||
"lodash.defaultsdeep": "^4.6.0",
|
||||
"lodash.mapvalues": "^4.6.0",
|
||||
"lodash.transform": "^4.6.0",
|
||||
"mini-css-extract-plugin": "^0.5.0",
|
||||
"mini-css-extract-plugin": "^0.6.0",
|
||||
"minimist": "^1.2.0",
|
||||
"ora": "^3.1.0",
|
||||
"ora": "^3.4.0",
|
||||
"portfinder": "^1.0.20",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"read-pkg": "^4.0.1",
|
||||
"semver": "^5.6.0",
|
||||
"read-pkg": "^5.0.0",
|
||||
"semver": "^6.0.0",
|
||||
"slash": "^2.0.0",
|
||||
"source-map-url": "^0.4.0",
|
||||
"ssri": "^6.0.1",
|
||||
"string.prototype.padend": "^3.0.0",
|
||||
"terser-webpack-plugin": "^1.2.2",
|
||||
"terser-webpack-plugin": "^1.2.3",
|
||||
"thread-loader": "^2.1.2",
|
||||
"url-loader": "^1.1.2",
|
||||
"vue-loader": "^15.6.4",
|
||||
"vue-loader": "^15.7.0",
|
||||
"webpack": ">=4 < 4.29",
|
||||
"webpack-bundle-analyzer": "^3.0.4",
|
||||
"webpack-bundle-analyzer": "^3.3.0",
|
||||
"webpack-chain": "^4.11.0",
|
||||
"webpack-dev-server": "^3.2.0",
|
||||
"webpack-dev-server": "^3.3.1",
|
||||
"webpack-merge": "^4.2.1",
|
||||
"yorkie": "^2.0.0"
|
||||
},
|
||||
@@ -82,11 +84,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"fibers": "^3.1.1",
|
||||
"sass": "^1.17.2",
|
||||
"sass": "^1.18.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"vue": "^2.6.7",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-template-compiler": "^2.6.7",
|
||||
"vue": "^2.6.10",
|
||||
"vue-router": "^3.0.3",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"vuex": "^3.0.1"
|
||||
},
|
||||
"publishConfig": {
|
||||
@@ -94,5 +96,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"gitHead": "0dc793497281718762a5477a3de4a7ee439cdda6"
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ const { execSync } = require('child_process')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const LRU = require('lru-cache')
|
||||
const semver = require('semver')
|
||||
|
||||
let _hasYarn
|
||||
const _yarnProjects = new LRU({
|
||||
@@ -77,6 +78,51 @@ exports.hasProjectGit = (cwd) => {
|
||||
return result
|
||||
}
|
||||
|
||||
let _hasPnpm
|
||||
let _hasPnpm3orLater
|
||||
const _pnpmProjects = new LRU({
|
||||
max: 10,
|
||||
maxAge: 1000
|
||||
})
|
||||
|
||||
exports.hasPnpm3OrLater = () => {
|
||||
if (process.env.VUE_CLI_TEST) {
|
||||
return true
|
||||
}
|
||||
if (_hasPnpm3orLater != null) {
|
||||
return _hasPnpm3orLater
|
||||
}
|
||||
try {
|
||||
const pnpmVersion = execSync('pnpm --version').toString()
|
||||
// there's a critical bug in pnpm 2
|
||||
// https://github.com/pnpm/pnpm/issues/1678#issuecomment-469981972
|
||||
// so we only support pnpm >= 3.0.0
|
||||
_hasPnpm = true
|
||||
_hasPnpm3orLater = semver.gte(pnpmVersion, '3.0.0')
|
||||
return _hasPnpm3orLater
|
||||
} catch (e) {
|
||||
return (_hasPnpm3orLater = false)
|
||||
}
|
||||
}
|
||||
|
||||
exports.hasProjectPnpm = (cwd) => {
|
||||
if (_pnpmProjects.has(cwd)) {
|
||||
return checkPnpm(_pnpmProjects.get(cwd))
|
||||
}
|
||||
|
||||
const lockFile = path.join(cwd, 'pnpm-lock.yaml')
|
||||
const result = fs.existsSync(lockFile)
|
||||
_pnpmProjects.set(cwd, result)
|
||||
return checkPnpm(result)
|
||||
}
|
||||
|
||||
function checkPnpm (result) {
|
||||
if (result && !exports.hasPnpm3OrLater()) {
|
||||
throw new Error(`The project seems to require pnpm${_hasPnpm ? ' >= 3' : ''} but it's not installed.`)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// OS
|
||||
exports.isWindows = process.platform === 'win32'
|
||||
exports.isMacintosh = process.platform === 'darwin'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-shared-utils",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "shared utilities for vue-cli packages",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -27,10 +27,10 @@
|
||||
"lru-cache": "^5.1.1",
|
||||
"node-ipc": "^9.1.1",
|
||||
"opn": "^5.3.0",
|
||||
"ora": "^3.1.0",
|
||||
"ora": "^3.4.0",
|
||||
"request": "^2.87.0",
|
||||
"request-promise-native": "^1.0.7",
|
||||
"semver": "^5.5.0",
|
||||
"semver": "^6.0.0",
|
||||
"string.prototype.padstart": "^3.0.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-test-utils",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"description": "test utilities for vue-cli packages",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -26,6 +26,6 @@
|
||||
"fs-extra": "^7.0.1",
|
||||
"json-server": "^0.14.0",
|
||||
"puppeteer": "^1.11.0",
|
||||
"strip-ansi": "^5.0.0"
|
||||
"strip-ansi": "^5.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ module.exports = {
|
||||
globals: {
|
||||
ClientAddonApi: false,
|
||||
mapSharedData: false,
|
||||
Vue: false
|
||||
Vue: false,
|
||||
name: 'off'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-ui-addon-webpack",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vuejs/vue-cli.git",
|
||||
@@ -18,11 +18,11 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^3.5.1",
|
||||
"@vue/cli-plugin-eslint": "^3.5.1",
|
||||
"@vue/cli-service": "^3.5.1",
|
||||
"@vue/cli-plugin-babel": "^3.6.0",
|
||||
"@vue/cli-plugin-eslint": "^3.6.0",
|
||||
"@vue/cli-service": "^3.6.0",
|
||||
"@vue/eslint-config-standard": "^4.0.0",
|
||||
"eslint": "^5.14.1",
|
||||
"eslint": "^5.16.0",
|
||||
"stylus": "^0.54.5",
|
||||
"stylus-loader": "^3.0.2",
|
||||
"vue-progress-path": "^0.0.2",
|
||||
@@ -35,5 +35,6 @@
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
},
|
||||
"gitHead": "0dc793497281718762a5477a3de4a7ee439cdda6"
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ export default {
|
||||
.title
|
||||
color lighten($vue-ui-color-dark, 60%)
|
||||
font-size 20px
|
||||
font-weight lighter
|
||||
font-weight 300
|
||||
text-align center
|
||||
margin-bottom $padding-item
|
||||
|
||||
@@ -108,7 +108,7 @@ export default {
|
||||
.info-block
|
||||
v-box()
|
||||
box-center()
|
||||
font-weight lighter
|
||||
font-weight 300
|
||||
text-align center
|
||||
|
||||
.label
|
||||
|
||||
@@ -17,6 +17,7 @@ module.exports = {
|
||||
globals: {
|
||||
ClientAddonApi: false,
|
||||
mapSharedData: false,
|
||||
Vue: false
|
||||
Vue: false,
|
||||
name: 'off'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-ui-addon-widgets",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vuejs/vue-cli.git",
|
||||
@@ -18,16 +18,17 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^3.5.1",
|
||||
"@vue/cli-plugin-eslint": "^3.5.1",
|
||||
"@vue/cli-service": "^3.5.1",
|
||||
"@vue/cli-plugin-babel": "^3.6.0",
|
||||
"@vue/cli-plugin-eslint": "^3.6.0",
|
||||
"@vue/cli-service": "^3.6.0",
|
||||
"@vue/eslint-config-standard": "^4.0.0",
|
||||
"eslint": "^5.14.1",
|
||||
"eslint": "^5.16.0",
|
||||
"stylus": "^0.54.5",
|
||||
"stylus-loader": "^3.0.2",
|
||||
"vue-template-compiler": "^2.5.21"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
},
|
||||
"gitHead": "0dc793497281718762a5477a3de4a7ee439cdda6"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-if="false" class="status-widget">
|
||||
<div v-if="implemented" class="status-widget">
|
||||
<div class="header">
|
||||
<div class="icon-wrapper">
|
||||
<ItemLogo
|
||||
@@ -14,9 +14,10 @@
|
||||
<div class="last-updated">
|
||||
<template v-if="status.lastUpdate">
|
||||
<div class="label">
|
||||
{{ $t('org.vue.widgets.status-widget.last-updated') }}
|
||||
{{ message || $t('org.vue.widgets.status-widget.last-updated') }}
|
||||
</div>
|
||||
<VueTimeago
|
||||
v-if="!message"
|
||||
:datetime="status.lastUpdate"
|
||||
:auto-update="60"
|
||||
/>
|
||||
@@ -73,6 +74,17 @@ export default {
|
||||
status: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
|
||||
message: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
|
||||
// TODO remove
|
||||
implemented: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -2,12 +2,23 @@
|
||||
<div class="vulnerability">
|
||||
<StatusWidget
|
||||
v-if="status"
|
||||
:icon="icons[status.status]"
|
||||
:icon-class="iconClasses[status.status]"
|
||||
:icon="status.status === 'attention' ? severity.icon : icons[status.status]"
|
||||
:icon-class="status.status === 'attention' ? severity.class : iconClasses[status.status]"
|
||||
:title="$t(`org.vue.widgets.vulnerability.messages.${status.status}`, { n: status.count })"
|
||||
:status="status"
|
||||
:message="status.message"
|
||||
implemented
|
||||
@check="checkForUpdates()"
|
||||
/>
|
||||
>
|
||||
<template #more-actions>
|
||||
<VueButton
|
||||
v-if="status.status !== 'loading'"
|
||||
:label="$t('org.vue.widgets.vulnerability.recheck')"
|
||||
icon-left="refresh"
|
||||
@click="refresh()"
|
||||
/>
|
||||
</template>
|
||||
</StatusWidget>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -18,8 +29,28 @@ import StatusWidget from './StatusWidget.vue'
|
||||
|
||||
const UPDATES_ICONS = {
|
||||
'ok': 'verified_user',
|
||||
'loading': 'hourglass_full',
|
||||
'attention': 'error'
|
||||
'loading': 'hourglass_empty',
|
||||
'attention': 'error',
|
||||
'error': 'error'
|
||||
}
|
||||
|
||||
export const SEVERITIES = {
|
||||
critical: {
|
||||
class: 'danger',
|
||||
icon: 'new_releases'
|
||||
},
|
||||
high: {
|
||||
class: 'danger',
|
||||
icon: 'error'
|
||||
},
|
||||
moderate: {
|
||||
class: 'warning',
|
||||
icon: 'error'
|
||||
},
|
||||
low: {
|
||||
class: '',
|
||||
icon: 'error'
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
@@ -33,14 +64,20 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
computed: {
|
||||
severity () {
|
||||
return this.status && SEVERITIES[this.status.severity]
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.icons = UPDATES_ICONS
|
||||
this.iconClasses = UPDATES_ICON_CLASSES
|
||||
},
|
||||
|
||||
methods: {
|
||||
checkForUpdates () {
|
||||
// TODO
|
||||
refresh () {
|
||||
this.$callPluginAction('org.vue.widgets.actions.check-vunerability')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,15 +12,48 @@
|
||||
<div class="title">
|
||||
{{ $t('org.vue.widgets.vulnerability.messages.attention', { n: details.vulnerabilities.length }) }}
|
||||
</div>
|
||||
|
||||
<div class="summary">
|
||||
<div
|
||||
v-for="(severity, key) of severities"
|
||||
:key="key"
|
||||
:class="`severity-${severity.class}`"
|
||||
class="summary-item"
|
||||
>
|
||||
<VueIcon
|
||||
:icon="severity.icon"
|
||||
:class="severity.class"
|
||||
/>
|
||||
<span class="count">{{ details.summary[key] }}</span>
|
||||
{{ $t(`org.vue.widgets.vulnerability.severity.${key}`) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="items">
|
||||
<VulnerabilityItem
|
||||
v-for="(item, index) of details.vulnerabilities"
|
||||
:key="index"
|
||||
:item="item"
|
||||
/>
|
||||
</div>
|
||||
<transition name="vue-ui-fade">
|
||||
<DynamicScroller
|
||||
v-if="showList"
|
||||
ref="scroller"
|
||||
class="items"
|
||||
:items="details.vulnerabilities"
|
||||
:min-item-size="75"
|
||||
v-slot="{ item, active }"
|
||||
>
|
||||
<DynamicScrollerItem
|
||||
:item="item"
|
||||
:active="active"
|
||||
:size-dependencies="[
|
||||
showMoreParentsMap[item.id]
|
||||
]"
|
||||
>
|
||||
<VulnerabilityItem
|
||||
:item="item"
|
||||
:show-more-parents="showMoreParentsMap[item.id]"
|
||||
@toggle-more-parents="$set(showMoreParentsMap, item.id, !showMoreParentsMap[item.id])"
|
||||
/>
|
||||
</DynamicScrollerItem>
|
||||
</DynamicScroller>
|
||||
</transition>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@@ -28,6 +61,8 @@
|
||||
<script>
|
||||
import VulnerabilityItem from './VulnerabilityItem.vue'
|
||||
|
||||
import { SEVERITIES } from './Vulnerability.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VulnerabilityItem
|
||||
@@ -37,6 +72,24 @@ export default {
|
||||
return mapSharedData('org.vue.widgets.vulnerability.', {
|
||||
details: 'details'
|
||||
})
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
showList: false,
|
||||
showMoreParentsMap: {}
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.severities = SEVERITIES
|
||||
},
|
||||
|
||||
mounted () {
|
||||
// Animation breaks scroller item sizes
|
||||
setTimeout(() => {
|
||||
this.showList = true
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -45,9 +98,32 @@ export default {
|
||||
@import "~@vue/cli-ui/src/style/imports"
|
||||
|
||||
.vulnerability-details
|
||||
overflow-x hidden
|
||||
overflow-y auto
|
||||
v-box()
|
||||
|
||||
.pane-toolbar
|
||||
padding-bottom $padding-item
|
||||
|
||||
.summary
|
||||
display flex
|
||||
padding-right 12px
|
||||
|
||||
.summary-item
|
||||
display flex
|
||||
align-items center
|
||||
margin-left 16px
|
||||
|
||||
.vue-ui-icon,
|
||||
.count
|
||||
margin-right 3px
|
||||
|
||||
.count
|
||||
font-weight bold
|
||||
|
||||
.severity-danger
|
||||
color $vue-ui-color-danger
|
||||
.severity-warning
|
||||
color $vue-ui-color-warning
|
||||
|
||||
.items
|
||||
flex 1
|
||||
</style>
|
||||
|
||||
@@ -2,84 +2,114 @@
|
||||
<div class="vulnerability-item list-item">
|
||||
<div class="wrapper">
|
||||
<ItemLogo
|
||||
image="error"
|
||||
:image="severity.icon"
|
||||
:class="severity.class"
|
||||
/>
|
||||
|
||||
<ListItemInfo
|
||||
:link="item.moreInfo"
|
||||
>
|
||||
<template slot="name">
|
||||
<span class="name">{{ item.name }}</span>
|
||||
<span class="version">{{ item.version }}</span>
|
||||
</template>
|
||||
|
||||
<template slot="description">
|
||||
<span
|
||||
class="severity"
|
||||
:class="severity.class"
|
||||
>
|
||||
{{ $t(`org.vue.widgets.vulnerability.severity.${item.severity}`) }}
|
||||
</span>
|
||||
|
||||
<span class="message">
|
||||
{{ item.message }}
|
||||
</span>
|
||||
</template>
|
||||
</ListItemInfo>
|
||||
|
||||
<div class="parents">
|
||||
<div v-if="!item.parents" class="vue-ui-empty">
|
||||
{{ $t('org.vue.widgets.vulnerability.direct-dep') }}
|
||||
</div>
|
||||
|
||||
<template v-else>
|
||||
<div
|
||||
v-for="(parent, index) of item.parents"
|
||||
:key="index"
|
||||
class="parent"
|
||||
>
|
||||
<span class="name">{{ parent.name }}</span>
|
||||
<span class="version">{{ parent.version }}</span>
|
||||
<VueIcon
|
||||
icon="chevron_right"
|
||||
class="separator-icon medium"
|
||||
/>
|
||||
</div>
|
||||
<div class="parent current">
|
||||
<div class="main-infos">
|
||||
<ListItemInfo
|
||||
:link="item.moreInfo"
|
||||
>
|
||||
<template slot="name">
|
||||
<span class="name">{{ item.name }}</span>
|
||||
<span class="version">{{ item.version }}</span>
|
||||
</template>
|
||||
|
||||
<template slot="description">
|
||||
<span
|
||||
class="severity"
|
||||
:class="severity.class"
|
||||
>
|
||||
{{ $t(`org.vue.widgets.vulnerability.severity.${item.severity}`) }}
|
||||
</span>
|
||||
<span class="title" v-tooltip="item.message">
|
||||
{{ item.title }}
|
||||
</span>
|
||||
</template>
|
||||
</ListItemInfo>
|
||||
|
||||
<div class="info-versions">
|
||||
<div class="info-version">
|
||||
<VueIcon icon="error"/>
|
||||
{{ $t('org.vue.widgets.vulnerability.versions.vulnerable') }}
|
||||
<span class="version">{{ item.versions.vulnerable }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="info-version">
|
||||
<VueIcon icon="check_circle"/>
|
||||
{{ $t('org.vue.widgets.vulnerability.versions.patched') }}
|
||||
<span class="version">{{ item.versions.patched }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="recommendation vue-ui-text success banner">
|
||||
<VueIcon icon="arrow_forward" class="big"/>
|
||||
{{ item.recommendation }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="parents-list">
|
||||
<div
|
||||
v-for="(parents, index) of displayedParents"
|
||||
:key="index"
|
||||
class="parents"
|
||||
>
|
||||
<div v-if="!parents.length" class="vue-ui-empty">
|
||||
{{ $t('org.vue.widgets.vulnerability.direct-dep') }}
|
||||
</div>
|
||||
|
||||
<template v-else>
|
||||
<div
|
||||
v-for="(parent, index) of parents"
|
||||
:key="index"
|
||||
class="parent"
|
||||
>
|
||||
<span class="name">{{ parent.name }}</span>
|
||||
<VueIcon
|
||||
icon="chevron_right"
|
||||
class="separator-icon medium"
|
||||
/>
|
||||
</div>
|
||||
<div class="parent current">
|
||||
<span class="name">{{ item.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div v-if="item.parents.length > 3" class="show-more">
|
||||
<VueButton
|
||||
:icon-left="showMoreParents ? 'expand_less' : 'expand_more'"
|
||||
class="flat"
|
||||
@click="$emit('toggle-more-parents')"
|
||||
>
|
||||
{{ $t(`org.vue.common.show-${showMoreParents ? 'less' : 'more'}`) }}
|
||||
</VueButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const SEVERITIES = {
|
||||
high: {
|
||||
class: 'danger'
|
||||
},
|
||||
medium: {
|
||||
class: 'warning'
|
||||
},
|
||||
low: {
|
||||
class: ''
|
||||
}
|
||||
}
|
||||
import { SEVERITIES } from './Vulnerability.vue'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
showMoreParents: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
severity () {
|
||||
return SEVERITIES[this.item.severity]
|
||||
},
|
||||
|
||||
displayedParents () {
|
||||
return this.showMoreParents ? this.item.parents : this.item.parents.slice(0, 3)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,13 +124,16 @@ export default {
|
||||
|
||||
.wrapper
|
||||
h-box()
|
||||
box-center()
|
||||
|
||||
.list-item-info
|
||||
.main-infos
|
||||
flex 1
|
||||
|
||||
.name
|
||||
font-weight bold
|
||||
.name
|
||||
font-weight bold
|
||||
|
||||
.title
|
||||
cursor help
|
||||
border-bottom 1px dotted
|
||||
|
||||
.version
|
||||
margin-left 4px
|
||||
@@ -108,14 +141,27 @@ export default {
|
||||
font-size .9em
|
||||
|
||||
.severity
|
||||
color $color-text-light
|
||||
color $vue-ui-color-dark
|
||||
.vue-ui-dark-mode &
|
||||
color $vue-ui-color-light
|
||||
&.danger
|
||||
color $vue-ui-color-danger
|
||||
&.warning
|
||||
color $vue-ui-color-warning
|
||||
|
||||
.parents-list
|
||||
margin-left 12px
|
||||
width 50%
|
||||
|
||||
.parents
|
||||
h-box()
|
||||
margin 12px 0
|
||||
flex-wrap wrap
|
||||
width 100%
|
||||
|
||||
.parent
|
||||
&:not(:first-child)
|
||||
opacity .7
|
||||
|
||||
.separator-icon
|
||||
>>> svg
|
||||
@@ -123,4 +169,24 @@ export default {
|
||||
|
||||
.vue-ui-empty
|
||||
padding 0
|
||||
|
||||
.info-versions
|
||||
margin-top 4px
|
||||
|
||||
.info-version
|
||||
display flex
|
||||
align-items baseline
|
||||
margin-top 2px
|
||||
|
||||
.vue-ui-icon
|
||||
margin-right 4px
|
||||
opacity .5
|
||||
|
||||
.version
|
||||
margin-left 8px
|
||||
|
||||
.recommendation
|
||||
margin 8px 0
|
||||
display inline-flex
|
||||
align-items center
|
||||
</style>
|
||||
|
||||
@@ -69,7 +69,7 @@ export default {
|
||||
|
||||
.title
|
||||
font-size 32px
|
||||
font-weight lighter
|
||||
font-weight 300
|
||||
text-align center
|
||||
margin-bottom ($padding-item * 2)
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ module.exports = {
|
||||
],
|
||||
|
||||
globals: {
|
||||
ClientAddonApi: false
|
||||
ClientAddonApi: false,
|
||||
name: 'off'
|
||||
},
|
||||
|
||||
plugins: [
|
||||
@@ -19,5 +20,9 @@ module.exports = {
|
||||
'vue/no-use-v-if-with-v-for': 'warn',
|
||||
'vue/no-unused-vars': 'warn',
|
||||
'vue/return-in-computed-property': 'warn',
|
||||
},
|
||||
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@ const { validateSuggestion } = require('./suggestion')
|
||||
const { validateProgress } = require('./progress')
|
||||
const { validateWidget } = require('./widget')
|
||||
|
||||
/**
|
||||
* @typedef SetSharedDataOptions
|
||||
* @prop {boolean} disk Don't keep this data in memory by writing it to disk
|
||||
*/
|
||||
|
||||
/** @typedef {import('../connectors/shared-data').SharedData} SharedData */
|
||||
|
||||
class PluginApi {
|
||||
constructor ({ plugins, file, project, lightMode = false }, context) {
|
||||
// Context
|
||||
@@ -453,10 +460,10 @@ class PluginApi {
|
||||
/* Namespaced */
|
||||
|
||||
/**
|
||||
* Retrieve a Shared data value.
|
||||
* Retrieve a Shared data instance.
|
||||
*
|
||||
* @param {string} id Id of the Shared data
|
||||
* @returns {any} Shared data value
|
||||
* @returns {SharedData} Shared data instance
|
||||
*/
|
||||
getSharedData (id) {
|
||||
return sharedData.get({ id, projectId: this.project.id }, this.context)
|
||||
@@ -467,9 +474,10 @@ class PluginApi {
|
||||
*
|
||||
* @param {string} id Id of the Shared data
|
||||
* @param {any} value Value of the Shared data
|
||||
* @param {SetSharedDataOptions} options
|
||||
*/
|
||||
setSharedData (id, value) {
|
||||
sharedData.set({ id, projectId: this.project.id, value }, this.context)
|
||||
async setSharedData (id, value, { disk = false } = {}) {
|
||||
return sharedData.set({ id, projectId: this.project.id, value, disk }, this.context)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -477,8 +485,8 @@ class PluginApi {
|
||||
*
|
||||
* @param {string} id Id of the Shared data
|
||||
*/
|
||||
removeSharedData (id) {
|
||||
sharedData.remove({ id, projectId: this.project.id }, this.context)
|
||||
async removeSharedData (id) {
|
||||
return sharedData.remove({ id, projectId: this.project.id }, this.context)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -616,24 +624,93 @@ class PluginApi {
|
||||
* - callAction
|
||||
*
|
||||
* @param {string} namespace Prefix to add to the id params
|
||||
* @returns {object} Namespaced methods
|
||||
*/
|
||||
namespace (namespace) {
|
||||
return {
|
||||
/**
|
||||
* Retrieve a Shared data instance.
|
||||
*
|
||||
* @param {string} id Id of the Shared data
|
||||
* @returns {SharedData} Shared data instance
|
||||
*/
|
||||
getSharedData: (id) => this.getSharedData(namespace + id),
|
||||
setSharedData: (id, value) => this.setSharedData(namespace + id, value),
|
||||
/**
|
||||
* Set or update the value of a Shared data
|
||||
*
|
||||
* @param {string} id Id of the Shared data
|
||||
* @param {any} value Value of the Shared data
|
||||
* @param {SetSharedDataOptions} options
|
||||
*/
|
||||
setSharedData: (id, value, options) => this.setSharedData(namespace + id, value, options),
|
||||
/**
|
||||
* Delete a shared data.
|
||||
*
|
||||
* @param {string} id Id of the Shared data
|
||||
*/
|
||||
removeSharedData: (id) => this.removeSharedData(namespace + id),
|
||||
/**
|
||||
* Watch for a value change of a shared data
|
||||
*
|
||||
* @param {string} id Id of the Shared data
|
||||
* @param {function} handler Callback
|
||||
*/
|
||||
watchSharedData: (id, handler) => this.watchSharedData(namespace + id, handler),
|
||||
/**
|
||||
* Delete the watcher of a shared data.
|
||||
*
|
||||
* @param {string} id Id of the Shared data
|
||||
* @param {function} handler Callback
|
||||
*/
|
||||
unwatchSharedData: (id, handler) => this.unwatchSharedData(namespace + id, handler),
|
||||
/**
|
||||
* Listener triggered when a Plugin action is called from a client addon component.
|
||||
*
|
||||
* @param {string} id Id of the action to listen
|
||||
* @param {any} cb Callback (ex: (params) => {} )
|
||||
*/
|
||||
onAction: (id, cb) => this.onAction(namespace + id, cb),
|
||||
/**
|
||||
* Call a Plugin action. This can also listened by client addon components.
|
||||
*
|
||||
* @param {string} id Id of the action
|
||||
* @param {object} params Params object passed as 1st argument to callbacks
|
||||
* @returns {Promise}
|
||||
*/
|
||||
callAction: (id, params) => this.callAction(namespace + id, params),
|
||||
/**
|
||||
* Retrieve a value from the local DB
|
||||
*
|
||||
* @param {string} id Path to the item
|
||||
* @returns Item value
|
||||
*/
|
||||
storageGet: (id) => this.storageGet(namespace + id),
|
||||
/**
|
||||
* Store a value into the local DB
|
||||
*
|
||||
* @param {string} id Path to the item
|
||||
* @param {any} value Value to be stored (must be serializable in JSON)
|
||||
*/
|
||||
storageSet: (id, value) => this.storageSet(namespace + id, value),
|
||||
/**
|
||||
* Add a suggestion for the user.
|
||||
*
|
||||
* @param {object} options Suggestion
|
||||
*/
|
||||
addSuggestion: (options) => {
|
||||
options.id = namespace + options.id
|
||||
return this.addSuggestion(options)
|
||||
},
|
||||
/**
|
||||
* Remove a suggestion
|
||||
*
|
||||
* @param {string} id Id of the suggestion
|
||||
*/
|
||||
removeSuggestion: (id) => this.removeSuggestion(namespace + id),
|
||||
/**
|
||||
* Register a widget for project dashboard
|
||||
*
|
||||
* @param {object} def Widget definition
|
||||
*/
|
||||
registerWidget: (def) => {
|
||||
def.id = namespace + def.id
|
||||
return this.registerWidget(def)
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
/** @typedef {'warn' | 'error' | 'info' | 'done'} LogType */
|
||||
|
||||
/**
|
||||
* @typedef Log
|
||||
* @prop {string} id
|
||||
* @prop {string} date
|
||||
* @prop {LogType} type
|
||||
* @prop {string} tag
|
||||
* @prop {string} message
|
||||
*/
|
||||
|
||||
const shortId = require('shortid')
|
||||
const { events } = require('@vue/cli-shared-utils/lib/logger')
|
||||
const { generateTitle } = require('@vue/cli/lib/util/clearConsole')
|
||||
@@ -6,9 +17,15 @@ const channels = require('../channels')
|
||||
// Context
|
||||
const getContext = require('../context')
|
||||
|
||||
/** @type {Log []} */
|
||||
let logs = []
|
||||
|
||||
/**
|
||||
* @param {Log} log
|
||||
* @param {any} context
|
||||
*/
|
||||
exports.add = function (log, context) {
|
||||
/** @type {Log} */
|
||||
const item = {
|
||||
id: shortId.generate(),
|
||||
date: new Date().toISOString(),
|
||||
|
||||
@@ -27,7 +27,8 @@ const {
|
||||
getPluginLink,
|
||||
resolveModule,
|
||||
loadModule,
|
||||
clearModule
|
||||
clearModule,
|
||||
execa
|
||||
} = require('@vue/cli-shared-utils')
|
||||
const {
|
||||
progress: installProgress,
|
||||
@@ -35,7 +36,6 @@ const {
|
||||
uninstallPackage,
|
||||
updatePackage
|
||||
} = require('@vue/cli/lib/util/installDeps')
|
||||
const invoke = require('@vue/cli/lib/invoke')
|
||||
const { getCommand } = require('../util/command')
|
||||
const ipc = require('../util/ipc')
|
||||
const { log } = require('../util/logger')
|
||||
@@ -446,7 +446,32 @@ function runInvoke (id, context) {
|
||||
currentPluginId = id
|
||||
// Allow plugins that don't have a generator
|
||||
if (resolveModule(`${id}/generator`, cwd.get())) {
|
||||
await invoke(id, prompts.getAnswers(), cwd.get())
|
||||
const child = execa('vue', [
|
||||
'invoke',
|
||||
id,
|
||||
'--$inlineOptions',
|
||||
JSON.stringify(prompts.getAnswers())
|
||||
], {
|
||||
cwd: cwd.get(),
|
||||
stdio: ['inherit', 'pipe', 'inherit']
|
||||
})
|
||||
|
||||
const onData = buffer => {
|
||||
const text = buffer.toString().trim()
|
||||
if (text) {
|
||||
setProgress({
|
||||
info: text
|
||||
})
|
||||
logs.add({
|
||||
type: 'info',
|
||||
message: text
|
||||
}, context)
|
||||
}
|
||||
}
|
||||
|
||||
child.stdout.on('data', onData)
|
||||
|
||||
await child
|
||||
}
|
||||
// Run plugin api
|
||||
runPluginApi(id, getApi(cwd.get()), context)
|
||||
|
||||
@@ -5,7 +5,7 @@ const Creator = require('@vue/cli/lib/Creator')
|
||||
const { getPromptModules } = require('@vue/cli/lib/util/createTools')
|
||||
const { getFeatures } = require('@vue/cli/lib/util/features')
|
||||
const { defaults } = require('@vue/cli/lib/options')
|
||||
const { toShortPluginId, clearModule } = require('@vue/cli-shared-utils')
|
||||
const { toShortPluginId, execa } = require('@vue/cli-shared-utils')
|
||||
const { progress: installProgress } = require('@vue/cli/lib/util/installDeps')
|
||||
const parseGitConfig = require('parse-git-config')
|
||||
// Connectors
|
||||
@@ -15,6 +15,7 @@ const prompts = require('./prompts')
|
||||
const folders = require('./folders')
|
||||
const plugins = require('./plugins')
|
||||
const locales = require('./locales')
|
||||
const logs = require('./logs')
|
||||
// Context
|
||||
const getContext = require('../context')
|
||||
// Utils
|
||||
@@ -258,52 +259,23 @@ async function create (input, context) {
|
||||
|
||||
const targetDir = path.join(cwd.get(), input.folder)
|
||||
|
||||
// Delete existing folder
|
||||
if (fs.existsSync(targetDir)) {
|
||||
if (input.force) {
|
||||
setProgress({
|
||||
info: 'Cleaning folder...'
|
||||
})
|
||||
await folders.delete(targetDir)
|
||||
setProgress({
|
||||
info: null
|
||||
})
|
||||
} else {
|
||||
throw new Error(`Folder ${targetDir} already exists`)
|
||||
}
|
||||
}
|
||||
|
||||
cwd.set(targetDir, context)
|
||||
creator.context = targetDir
|
||||
|
||||
process.env.VUE_CLI_CONTEXT = targetDir
|
||||
clearModule('@vue/cli-service/webpack.config.js', targetDir)
|
||||
|
||||
const inCurrent = input.folder === '.'
|
||||
const name = inCurrent ? path.relative('../', process.cwd()) : input.folder
|
||||
creator.name = name.toLowerCase()
|
||||
const name = creator.name = (inCurrent ? path.relative('../', process.cwd()) : input.folder).toLowerCase()
|
||||
|
||||
// Answers
|
||||
const answers = prompts.getAnswers()
|
||||
await prompts.reset()
|
||||
let index
|
||||
|
||||
// Config files
|
||||
let index
|
||||
if ((index = answers.features.indexOf('use-config-files')) !== -1) {
|
||||
answers.features.splice(index, 1)
|
||||
answers.useConfigFiles = 'files'
|
||||
}
|
||||
|
||||
const createOptions = {
|
||||
packageManager: input.packageManager
|
||||
}
|
||||
// Git
|
||||
if (input.enableGit && input.gitCommitMessage) {
|
||||
createOptions.git = input.gitCommitMessage
|
||||
} else {
|
||||
createOptions.git = input.enableGit
|
||||
}
|
||||
|
||||
// Preset
|
||||
answers.preset = input.preset
|
||||
if (input.save) {
|
||||
@@ -329,7 +301,49 @@ async function create (input, context) {
|
||||
})
|
||||
|
||||
// Create
|
||||
await creator.create(createOptions, preset)
|
||||
const args = [
|
||||
'--skipGetStarted'
|
||||
]
|
||||
if (input.packageManager) args.push('--packageManager', input.packageManager)
|
||||
if (input.bar) args.push('--bare')
|
||||
if (input.force) args.push('--force')
|
||||
// Git
|
||||
if (input.enableGit && input.gitCommitMessage) {
|
||||
args.push('--git', input.gitCommitMessage)
|
||||
} else if (!input.enableGit) {
|
||||
args.push('--no-git')
|
||||
}
|
||||
// Preset
|
||||
args.push('--inlinePreset', JSON.stringify(preset))
|
||||
|
||||
log('create', name, args)
|
||||
|
||||
const child = execa('vue', [
|
||||
'create',
|
||||
name,
|
||||
...args
|
||||
], {
|
||||
cwd: cwd.get(),
|
||||
stdio: ['inherit', 'pipe', 'inherit']
|
||||
})
|
||||
|
||||
const onData = buffer => {
|
||||
const text = buffer.toString().trim()
|
||||
if (text) {
|
||||
setProgress({
|
||||
info: text
|
||||
})
|
||||
logs.add({
|
||||
type: 'info',
|
||||
message: text
|
||||
}, context)
|
||||
}
|
||||
}
|
||||
|
||||
child.stdout.on('data', onData)
|
||||
|
||||
await child
|
||||
|
||||
removeCreator()
|
||||
|
||||
notify({
|
||||
|
||||
@@ -2,7 +2,22 @@
|
||||
const channels = require('../channels')
|
||||
// Utils
|
||||
const { log } = require('../util/logger')
|
||||
const path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
const { rcFolder } = require('../util/rcFolder')
|
||||
|
||||
/**
|
||||
* @typedef SharedData
|
||||
* @prop {string} id
|
||||
* @prop {any} value
|
||||
* @prop {Date} updated
|
||||
* @prop {boolean} disk
|
||||
*/
|
||||
|
||||
const rootFolder = path.resolve(rcFolder, 'shared-data')
|
||||
fs.ensureDirSync(rootFolder)
|
||||
|
||||
/** @type {Map<string, Map<string, SharedData>>} */
|
||||
const sharedData = new Map()
|
||||
let watchers = new Map()
|
||||
|
||||
@@ -10,22 +25,47 @@ function get ({ id, projectId }, context) {
|
||||
const store = sharedData.get(projectId)
|
||||
if (!store) return null
|
||||
|
||||
const value = store.get(id)
|
||||
if (typeof value === 'undefined') return null
|
||||
|
||||
return {
|
||||
id,
|
||||
value
|
||||
let data = store.get(id)
|
||||
if (data == null) {
|
||||
if (fs.existsSync(path.resolve(rootFolder, projectId, `${id}.json`))) {
|
||||
data = {
|
||||
id,
|
||||
updated: new Date(),
|
||||
disk: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data && data.disk) {
|
||||
data.value = readOnDisk({ id, projectId }, context)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
function set ({ id, projectId, value }, context) {
|
||||
async function readOnDisk ({ id, projectId }, context) {
|
||||
const file = path.resolve(rootFolder, projectId, `${id}.json`)
|
||||
if (await fs.exists(file)) {
|
||||
return fs.readJson(file)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
async function set ({ id, projectId, value, disk = false }, context) {
|
||||
if (disk) {
|
||||
await writeOnDisk({ id, projectId, value }, context)
|
||||
}
|
||||
let store = sharedData.get(projectId)
|
||||
if (!store) {
|
||||
store = new Map()
|
||||
sharedData.set(projectId, store)
|
||||
}
|
||||
store.set(id, value)
|
||||
store.set(id, {
|
||||
id,
|
||||
...(disk ? {} : { value }),
|
||||
disk,
|
||||
updated: new Date()
|
||||
})
|
||||
|
||||
context.pubsub.publish(channels.SHARED_DATA_UPDATED, {
|
||||
sharedDataUpdated: { id, projectId, value }
|
||||
@@ -36,9 +76,19 @@ function set ({ id, projectId, value }, context) {
|
||||
return { id, value }
|
||||
}
|
||||
|
||||
function remove ({ id, projectId }, context) {
|
||||
async function writeOnDisk ({ id, projectId, value }, context) {
|
||||
const projectFolder = path.resolve(rootFolder, projectId)
|
||||
await fs.ensureDir(projectFolder)
|
||||
await fs.writeJson(path.resolve(projectFolder, `${id}.json`), value)
|
||||
}
|
||||
|
||||
async function remove ({ id, projectId }, context) {
|
||||
const store = sharedData.get(projectId)
|
||||
if (store) {
|
||||
const data = store.get(id)
|
||||
if (data && data.disk) {
|
||||
fs.remove(path.resolve(rootFolder, projectId, `${id}.json`))
|
||||
}
|
||||
store.delete(id)
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,8 @@ async function list ({ file = null, api = true } = {}, context) {
|
||||
const pluginApi = api && plugins.getApi(file)
|
||||
|
||||
// Get current valid tasks in project `package.json`
|
||||
let currentTasks = Object.keys(pkg.scripts).map(
|
||||
const scriptKeys = Object.keys(pkg.scripts)
|
||||
let currentTasks = scriptKeys.map(
|
||||
name => {
|
||||
const id = `${file}:${name}`
|
||||
existing.set(id, true)
|
||||
@@ -121,6 +122,14 @@ async function list ({ file = null, api = true } = {}, context) {
|
||||
// Add the new tasks
|
||||
list = list.concat(newTasks)
|
||||
|
||||
// Sort
|
||||
const getSortScore = task => {
|
||||
const index = scriptKeys.indexOf(task.name)
|
||||
if (index !== -1) return index
|
||||
return Infinity
|
||||
}
|
||||
list = list.sort((a, b) => getSortScore(a) - getSortScore(b))
|
||||
|
||||
tasks.set(file, list)
|
||||
}
|
||||
return list
|
||||
|
||||
@@ -44,6 +44,7 @@ enum ProjectType {
|
||||
input ProjectCreateInput {
|
||||
folder: String!
|
||||
force: Boolean!
|
||||
bare: Boolean!
|
||||
packageManager: PackageManager
|
||||
preset: String!
|
||||
remote: String
|
||||
|
||||
@@ -8,11 +8,21 @@ const plugins = require('./connectors/plugins')
|
||||
const distPath = path.resolve(__dirname, '../dist')
|
||||
const publicPath = path.resolve(__dirname, '../ui-public')
|
||||
|
||||
const CACHE_CONTROL = 'no-store, no-cache, must-revalidate, private'
|
||||
|
||||
module.exports = app => {
|
||||
app.use(express.static(distPath, { maxAge: 0 }))
|
||||
app.use('/public', express.static(publicPath, { maxAge: 0 }))
|
||||
app.use(express.static(distPath, { setHeaders }))
|
||||
app.use('/public', express.static(publicPath, { setHeaders }))
|
||||
app.use('/_plugin/:id/*', plugins.serve)
|
||||
app.use('/_plugin-logo/:id', plugins.serveLogo)
|
||||
app.use('/_addon/:id/*', clientAddons.serve)
|
||||
app.use(fallback(path.join(distPath, 'index.html'), { maxAge: 0 }))
|
||||
app.use(fallback(path.join(distPath, 'index.html'), {
|
||||
headers: {
|
||||
'Cache-Control': CACHE_CONTROL
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
function setHeaders (res, path, stat) {
|
||||
res.set('Cache-Control', CACHE_CONTROL)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ scalar JSON
|
||||
enum PackageManager {
|
||||
npm
|
||||
yarn
|
||||
pnpm
|
||||
}
|
||||
|
||||
interface DescribedEntity {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
const {
|
||||
hasYarn,
|
||||
hasProjectYarn
|
||||
hasProjectYarn,
|
||||
hasPnpm3OrLater,
|
||||
hasProjectPnpm
|
||||
} = require('@vue/cli-shared-utils')
|
||||
const { loadOptions } = require('@vue/cli/lib/options')
|
||||
|
||||
exports.getCommand = function (cwd = undefined) {
|
||||
if (!cwd) {
|
||||
return loadOptions().packageManager || (hasYarn() ? 'yarn' : 'npm')
|
||||
return loadOptions().packageManager || (hasYarn() ? 'yarn' : hasPnpm3OrLater() ? 'pnpm' : 'npm')
|
||||
}
|
||||
return hasProjectYarn(cwd) ? 'yarn' : 'npm'
|
||||
return hasProjectYarn(cwd) ? 'yarn' : hasProjectPnpm() ? 'pnpm' : 'npm'
|
||||
}
|
||||
|
||||
@@ -1,27 +1,9 @@
|
||||
const Lowdb = require('lowdb')
|
||||
const FileSync = require('lowdb/adapters/FileSync')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const { getRcPath } = require('@vue/cli/lib/util/rcPath')
|
||||
const { rcFolder } = require('./rcFolder')
|
||||
|
||||
let folder
|
||||
|
||||
if (process.env.VUE_CLI_UI_TEST) {
|
||||
folder = '../../live-test'
|
||||
// Clean DB
|
||||
fs.removeSync(path.resolve(__dirname, folder))
|
||||
} else if (process.env.VUE_APP_CLI_UI_DEV) {
|
||||
folder = '../../live'
|
||||
} else {
|
||||
folder = (
|
||||
process.env.VUE_CLI_UI_DB_PATH ||
|
||||
getRcPath('.vue-cli-ui')
|
||||
)
|
||||
}
|
||||
|
||||
fs.ensureDirSync(path.resolve(__dirname, folder))
|
||||
|
||||
const db = new Lowdb(new FileSync(path.resolve(__dirname, folder, 'db.json')))
|
||||
const db = new Lowdb(new FileSync(path.resolve(rcFolder, 'db.json')))
|
||||
|
||||
// Seed an empty DB
|
||||
db.defaults({
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
|
||||
const { getRcPath } = require('@vue/cli/lib/util/rcPath')
|
||||
|
||||
let folder
|
||||
|
||||
if (process.env.VUE_CLI_UI_TEST) {
|
||||
folder = path.resolve(__dirname, '../../live-test')
|
||||
// Clean DB
|
||||
fs.removeSync(path.resolve(__dirname, folder))
|
||||
} else if (process.env.VUE_APP_CLI_UI_DEV) {
|
||||
folder = path.resolve(__dirname, '../../live')
|
||||
} else {
|
||||
folder = (
|
||||
path.resolve(__dirname, process.env.VUE_CLI_UI_DB_PATH) ||
|
||||
getRcPath('.vue-cli-ui')
|
||||
)
|
||||
}
|
||||
|
||||
fs.ensureDirSync(path.resolve(__dirname, folder))
|
||||
|
||||
exports.rcFolder = folder
|
||||
@@ -4,7 +4,9 @@
|
||||
"common": {
|
||||
"close": "Close",
|
||||
"back": "Go back",
|
||||
"more-info": "More info"
|
||||
"more-info": "More info",
|
||||
"show-more": "Show more",
|
||||
"show-less": "Show less"
|
||||
},
|
||||
"components": {
|
||||
"client-addon-component": {
|
||||
@@ -118,7 +120,11 @@
|
||||
"update": "Update {target}",
|
||||
"refresh": "Force Refresh {target}<br><i>Press [Shift] for Quick Refresh (node_modules won't be updated)</i>"
|
||||
},
|
||||
"local": "Local"
|
||||
"local": "Local",
|
||||
"features": {
|
||||
"generator": "This plugin has a generator and can modify your project files and add new files for you.",
|
||||
"ui-integration": "This plugin includes additional UI features like enhanced tasks, configuration screens, dashboard widgets..."
|
||||
}
|
||||
},
|
||||
"project-dependency-item": {
|
||||
"version": "version",
|
||||
@@ -169,7 +175,8 @@
|
||||
"terminal-view": {
|
||||
"buttons": {
|
||||
"clear": "Clear console",
|
||||
"scroll": "Scroll to bottom"
|
||||
"scroll": "Scroll to bottom",
|
||||
"content-copy": "Copy content"
|
||||
}
|
||||
},
|
||||
"top-bar": {
|
||||
@@ -280,6 +287,7 @@
|
||||
"options": {
|
||||
"label": "Additional options",
|
||||
"force": "Overwrite target folder if it exists",
|
||||
"bare": "Scaffold project without beginner instructions",
|
||||
"git-title": "Git repository",
|
||||
"git": "Initialize git repository (recommended)",
|
||||
"git-commit-message": "Initial commit message (optional)"
|
||||
@@ -427,7 +435,8 @@
|
||||
}
|
||||
},
|
||||
"project-tasks": {
|
||||
"title": "Project tasks"
|
||||
"title": "Project tasks",
|
||||
"refresh": "Refresh tasks"
|
||||
},
|
||||
"project-task-details": {
|
||||
"actions": {
|
||||
@@ -806,15 +815,22 @@
|
||||
"description": "Check for known vulnerabilities in your project dependencies",
|
||||
"messages": {
|
||||
"ok": "No vulnerability found",
|
||||
"loading": "Checking security reports...",
|
||||
"attention": "{n} vulnerabilities found"
|
||||
"loading": "Auditing project security...",
|
||||
"attention": "{n} vulnerabilities found",
|
||||
"error": "Couldn't check for vulnerability"
|
||||
},
|
||||
"severity": {
|
||||
"critical": "Critical severity",
|
||||
"high": "High severity",
|
||||
"medium": "Medium severity",
|
||||
"moderate": "Medium severity",
|
||||
"low": "Low severity"
|
||||
},
|
||||
"direct-dep": "Direct dependency"
|
||||
"direct-dep": "Direct dependency",
|
||||
"versions": {
|
||||
"vulnerable": "Vulnerable versions:",
|
||||
"patched": "Patched versions:"
|
||||
},
|
||||
"recheck": "Check again"
|
||||
},
|
||||
"run-task": {
|
||||
"title": "Run task",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-ui",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vuejs/vue-cli.git",
|
||||
@@ -11,6 +11,7 @@
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint src apollo-server",
|
||||
"apollo": "cross-env VUE_APP_CLI_UI_DEV=true VUE_APP_GRAPHQL_PORT=4030 vue-cli-service apollo:watch",
|
||||
"apollo:debug": "cross-env VUE_CLI_DEBUG=true yarn run apollo",
|
||||
"apollo:run": "cross-env VUE_CLI_PLUGIN_DEV=true VUE_CLI_IPC=vue-cli-dev vue-cli-service apollo:run",
|
||||
"apollo:run:test": "cross-env VUE_CLI_DEBUG=true VUE_CLI_UI_TEST=true VUE_APP_GRAPHQL_PORT=4040 VUE_APP_CLI_UI_URL=ws://localhost:4040/graphql VUE_CLI_IPC=vue-cli-test vue-cli-service apollo:watch --mode production",
|
||||
"prepublishOnly": "yarn run lint --no-fix && yarn run build",
|
||||
@@ -33,19 +34,20 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@akryum/winattr": "^3.0.0",
|
||||
"@vue/cli-shared-utils": "^3.5.1",
|
||||
"@vue/cli-shared-utils": "^3.6.0",
|
||||
"chalk": "^2.4.1",
|
||||
"clone": "^2.1.1",
|
||||
"deepmerge": "^3.2.0",
|
||||
"execa": "^1.0.0",
|
||||
"express-history-api-fallback": "^2.2.1",
|
||||
"fkill": "^5.3.0",
|
||||
"fkill": "^6.1.0",
|
||||
"fs-extra": "^7.0.1",
|
||||
"globby": "^9.0.0",
|
||||
"graphql-subscriptions": "^1.1.0",
|
||||
"graphql-tag": "^2.9.2",
|
||||
"graphql-type-json": "^0.2.1",
|
||||
"graphql-type-json": "^0.2.4",
|
||||
"javascript-stringify": "^1.6.0",
|
||||
"js-yaml": "^3.12.0",
|
||||
"js-yaml": "^3.13.1",
|
||||
"lodash.merge": "^4.6.1",
|
||||
"lowdb": "^1.0.0",
|
||||
"lru-cache": "^5.1.1",
|
||||
@@ -53,42 +55,43 @@
|
||||
"node-notifier": "^5.4.0",
|
||||
"parse-git-config": "^2.0.2",
|
||||
"portfinder": "^1.0.13",
|
||||
"prismjs": "^1.15.0",
|
||||
"rss-parser": "^3.4.3",
|
||||
"semver": "^5.5.0",
|
||||
"prismjs": "^1.16.0",
|
||||
"rss-parser": "^3.7.0",
|
||||
"semver": "^6.0.0",
|
||||
"shortid": "^2.2.11",
|
||||
"vue-cli-plugin-apollo": "^0.19.1",
|
||||
"vue-cli-plugin-apollo": "^0.19.2",
|
||||
"vue-virtual-scroller": "^1.0.0-rc.2",
|
||||
"watch": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^3.5.1",
|
||||
"@vue/cli-plugin-e2e-cypress": "^3.5.1",
|
||||
"@vue/cli-plugin-eslint": "^3.5.1",
|
||||
"@vue/cli-service": "^3.5.1",
|
||||
"@vue/cli-plugin-babel": "^3.6.0",
|
||||
"@vue/cli-plugin-e2e-cypress": "^3.6.0",
|
||||
"@vue/cli-plugin-eslint": "^3.6.0",
|
||||
"@vue/cli-service": "^3.6.0",
|
||||
"@vue/eslint-config-standard": "^4.0.0",
|
||||
"@vue/ui": "^0.5.5",
|
||||
"@vue/ui": "^0.9.1",
|
||||
"ansi_up": "^3.0.0",
|
||||
"cross-env": "^5.1.5",
|
||||
"eslint": "^5.8.0",
|
||||
"eslint-plugin-graphql": "^3.0.1",
|
||||
"lint-staged": "^8.1.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-graphql": "^3.0.3",
|
||||
"lint-staged": "^8.1.5",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"portal-vue": "^1.3.0",
|
||||
"rimraf": "^2.6.2",
|
||||
"start-server-and-test": "^1.4.1",
|
||||
"start-server-and-test": "^1.7.13",
|
||||
"stylus": "^0.54.5",
|
||||
"stylus-loader": "^3.0.1",
|
||||
"vue": "^2.6.7",
|
||||
"vue": "^2.6.10",
|
||||
"vue-apollo": "^3.0.0-beta.25",
|
||||
"vue-color": "^2.4.6",
|
||||
"vue-i18n": "^8.8.2",
|
||||
"vue-i18n": "^8.10.0",
|
||||
"vue-instantsearch": "^1.5.1",
|
||||
"vue-meta": "^1.5.0",
|
||||
"vue-meta": "^1.6.0",
|
||||
"vue-observe-visibility": "^0.4.1",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-template-compiler": "^2.6.7",
|
||||
"vue-timeago": "^5.0.0",
|
||||
"xterm": "^3.11.0"
|
||||
"vue-router": "^3.0.3",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"vue-timeago": "^5.1.2",
|
||||
"xterm": "^3.12.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
@@ -120,5 +123,6 @@
|
||||
"ui": [
|
||||
"ui-dev.js"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gitHead": "0dc793497281718762a5477a3de4a7ee439cdda6"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="app-loading">
|
||||
<transition name="vue-ui-fade">
|
||||
<transition name="vue-ui-fade" appear>
|
||||
<VueLoadingIndicator
|
||||
v-if="loading"
|
||||
class="primary"
|
||||
|
||||
@@ -32,9 +32,11 @@
|
||||
</div>
|
||||
|
||||
<div class="secondary-info">
|
||||
<div v-if="progress.info" class="info">
|
||||
{{ progress.info }}
|
||||
</div>
|
||||
<div
|
||||
v-if="progress.info"
|
||||
class="info"
|
||||
v-html="ansiColors(progress.info)"
|
||||
/>
|
||||
|
||||
<VueLoadingBar
|
||||
v-if="progress.progress !== -1"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
:value="projectCurrent.favorite"
|
||||
:icon="projectCurrent.favorite ? 'star' : 'star_border'"
|
||||
class="extend-left"
|
||||
@input="toggleCurrentFavorite()"
|
||||
@update="toggleCurrentFavorite()"
|
||||
>
|
||||
{{ $t('org.vue.components.project-select-list-item.tooltips.favorite') }}
|
||||
</VueSwitch>
|
||||
@@ -89,7 +89,6 @@ import PROJECTS from '@/graphql/project/projects.gql'
|
||||
import PROJECT_OPEN from '@/graphql/project/projectOpen.gql'
|
||||
import PROJECT_SET_FAVORITE from '@/graphql/project/projectSetFavorite.gql'
|
||||
import OPEN_IN_EDITOR from '@/graphql/file/fileOpenInEditor.gql'
|
||||
import CURRENT_PROJECT_ID_SET from '@/graphql/project/currentProjectIdSet.gql'
|
||||
|
||||
export default {
|
||||
apollo: {
|
||||
@@ -125,13 +124,6 @@ export default {
|
||||
})
|
||||
|
||||
await resetApollo()
|
||||
|
||||
await this.$apollo.mutate({
|
||||
mutation: CURRENT_PROJECT_ID_SET,
|
||||
variables: {
|
||||
projectId: project.id
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
async toggleCurrentFavorite () {
|
||||
|
||||
@@ -31,5 +31,5 @@
|
||||
|
||||
.title
|
||||
font-size 28px
|
||||
font-weight lighter
|
||||
font-weight 300
|
||||
</style>
|
||||
|
||||
@@ -112,7 +112,7 @@ export default {
|
||||
padding $padding-item
|
||||
font-size 24px
|
||||
text-align center
|
||||
font-weight lighter
|
||||
font-weight 300
|
||||
|
||||
&.hide-tabs
|
||||
>>> .tabs
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
icon="lens"
|
||||
class="separator"
|
||||
/>
|
||||
<VueButton
|
||||
class="icon-button flat"
|
||||
icon-left="content_copy"
|
||||
v-tooltip="$t('org.vue.components.terminal-view.buttons.content-copy')"
|
||||
@click="copyContent()"
|
||||
/>
|
||||
<VueButton
|
||||
class="icon-button flat"
|
||||
icon-left="subdirectory_arrow_left"
|
||||
@@ -196,6 +202,29 @@ export default {
|
||||
this.$_terminal.scrollToBottom()
|
||||
},
|
||||
|
||||
copyContent () {
|
||||
const textarea = this.$_terminal.textarea
|
||||
if (!textarea) {
|
||||
return
|
||||
}
|
||||
const textValue = textarea.value
|
||||
const emptySelection = !this.$_terminal.hasSelection()
|
||||
try {
|
||||
if (emptySelection) {
|
||||
this.$_terminal.selectAll()
|
||||
}
|
||||
var selection = this.$_terminal.getSelection()
|
||||
textarea.value = selection
|
||||
textarea.select()
|
||||
document.execCommand('copy')
|
||||
} finally {
|
||||
textarea.value = textValue
|
||||
if (emptySelection) {
|
||||
this.$_terminal.clearSelection()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleLink (event, uri) {
|
||||
if (this.openLinks) {
|
||||
window.open(uri, '_blank')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<transition duration="150">
|
||||
<transition duration="150" appear>
|
||||
<div
|
||||
class="widget"
|
||||
:class="{
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
slot-scope="{ result }"
|
||||
:pkg="result"
|
||||
:selected="selectedIdModel === result.name"
|
||||
:try-logo="tryLogos"
|
||||
:load-metadata="loadMetadata"
|
||||
@click.native="selectedIdModel = result.name"
|
||||
/>
|
||||
</ais-results>
|
||||
@@ -98,7 +98,7 @@ export default {
|
||||
default: 20
|
||||
},
|
||||
|
||||
tryLogos: {
|
||||
loadMetadata: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
|
||||
@@ -49,6 +49,27 @@
|
||||
</span>
|
||||
</template>
|
||||
</ListItemInfo>
|
||||
|
||||
<div
|
||||
v-if="hasGenerator"
|
||||
class="feature"
|
||||
v-tooltip="$t('org.vue.components.project-plugin-item.features.generator')"
|
||||
>
|
||||
<VueIcon
|
||||
icon="note_add"
|
||||
class="big"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="hasUiIntegration"
|
||||
class="feature"
|
||||
v-tooltip="$t('org.vue.components.project-plugin-item.features.ui-integration')"
|
||||
>
|
||||
<VueIcon
|
||||
icon="brush"
|
||||
class="big"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -65,7 +86,7 @@ export default {
|
||||
default: false
|
||||
},
|
||||
|
||||
tryLogo: {
|
||||
loadMetadata: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
@@ -73,7 +94,9 @@ export default {
|
||||
|
||||
data () {
|
||||
return {
|
||||
logoUrl: null
|
||||
logoUrl: null,
|
||||
hasGenerator: false,
|
||||
hasUiIntegration: false
|
||||
}
|
||||
},
|
||||
|
||||
@@ -85,25 +108,38 @@ export default {
|
||||
|
||||
watch: {
|
||||
'pkg.name': {
|
||||
handler: 'updateLogo',
|
||||
handler: 'updateMetadata',
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateLogo () {
|
||||
updateMetadata () {
|
||||
const name = this.pkg.name
|
||||
|
||||
this.hasUiIntegration = false
|
||||
this.hasGenerator = false
|
||||
// By default, show the npm user avatar
|
||||
this.logoUrl = this.pkg.owner.avatar
|
||||
|
||||
// Try to load the logo.png file inside the package
|
||||
if (this.tryLogo) {
|
||||
const name = this.pkg.name
|
||||
if (this.loadMetadata) {
|
||||
const img = new Image()
|
||||
img.onload = () => {
|
||||
if (name !== this.pkg.name) return
|
||||
this.logoUrl = img.src
|
||||
}
|
||||
img.src = `https://unpkg.com/${name}/logo.png`
|
||||
|
||||
fetch(`https://unpkg.com/${name}/ui`).then(response => {
|
||||
if (name !== this.pkg.name) return
|
||||
this.hasUiIntegration = response.ok
|
||||
})
|
||||
|
||||
fetch(`https://unpkg.com/${name}/generator`).then(response => {
|
||||
if (name !== this.pkg.name) return
|
||||
this.hasGenerator = response.ok
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,4 +183,10 @@ export default {
|
||||
&.owner
|
||||
.vue-ui-icon
|
||||
margin-right 2px
|
||||
|
||||
.feature
|
||||
margin-right 12px
|
||||
opacity .3
|
||||
&:hover
|
||||
opacity 1
|
||||
</style>
|
||||
|
||||
@@ -133,6 +133,7 @@ import GIT_COMMIT from '@/graphql/git/gitCommit.gql'
|
||||
|
||||
const defaultCollapsed = [
|
||||
'yarn.lock',
|
||||
'pnpm-lock.yaml',
|
||||
'package-lock.json'
|
||||
]
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
>
|
||||
<NpmPackageSearch
|
||||
filters="computedKeywords:vue-cli-plugin"
|
||||
try-logos
|
||||
load-metadata
|
||||
@close="close()"
|
||||
@install="installPlugin"
|
||||
>
|
||||
|
||||
@@ -96,6 +96,10 @@
|
||||
value="yarn"
|
||||
label="yarn"
|
||||
/>
|
||||
<VueSelectButton
|
||||
value="pnpm"
|
||||
label="pnpm"
|
||||
/>
|
||||
</VueSelect>
|
||||
</VueFormField>
|
||||
|
||||
@@ -108,6 +112,13 @@
|
||||
>
|
||||
{{ $t('org.vue.views.project-create.tabs.details.form.options.force') }}
|
||||
</VueSwitch>
|
||||
|
||||
<VueSwitch
|
||||
v-model="formData.bare"
|
||||
class="extend-left bare"
|
||||
>
|
||||
{{ $t('org.vue.views.project-create.tabs.details.form.options.bare') }}
|
||||
</VueSwitch>
|
||||
</VueFormField>
|
||||
|
||||
<VueFormField
|
||||
@@ -466,6 +477,7 @@ function formDataFactory () {
|
||||
return {
|
||||
folder: '',
|
||||
force: false,
|
||||
bare: false,
|
||||
enableGit: true,
|
||||
gitCommitMessage: '',
|
||||
packageManager: undefined,
|
||||
@@ -629,6 +641,7 @@ export default {
|
||||
input: {
|
||||
folder: this.formData.folder,
|
||||
force: this.formData.force,
|
||||
bare: this.formData.bare,
|
||||
enableGit: this.formData.enableGit,
|
||||
gitCommitMessage: this.formData.gitCommitMessage,
|
||||
packageManager: this.formData.packageManager,
|
||||
|
||||
@@ -27,6 +27,13 @@
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<VueButton
|
||||
icon-left="open_in_browser"
|
||||
@click.stop="openInEditor()"
|
||||
>
|
||||
{{ $t('org.vue.components.project-select-list-item.tooltips.open-in-editor') }}
|
||||
</VueButton>
|
||||
|
||||
<VueButton
|
||||
v-if="project.homepage"
|
||||
:href="project.homepage"
|
||||
@@ -37,13 +44,6 @@
|
||||
@click.stop
|
||||
/>
|
||||
|
||||
<VueButton
|
||||
class="icon-button"
|
||||
icon-left="open_in_browser"
|
||||
v-tooltip="$t('org.vue.components.project-select-list-item.tooltips.open-in-editor')"
|
||||
@click.stop="openInEditor()"
|
||||
/>
|
||||
|
||||
<VueButton
|
||||
class="icon-button"
|
||||
icon-left="close"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
:value="isCheckboxSelected(choice)"
|
||||
:disabled="choice.disabled"
|
||||
class="right"
|
||||
@input="value => asnwerCheckbox(choice, value)"
|
||||
@update="value => asnwerCheckbox(choice, value)"
|
||||
>
|
||||
{{ $t(choice.name) }}
|
||||
</VueSwitch>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<VueInput
|
||||
slot="trigger"
|
||||
:value="value(prompt.value)"
|
||||
@input="value => answer(value)"
|
||||
@update="value => answer(value)"
|
||||
>
|
||||
<div slot="right" class="color-preview">
|
||||
<div class="color-swatch" :style="{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<VueSwitch
|
||||
:value="value(prompt.value)"
|
||||
class="extend-left"
|
||||
@input="value => answer(value)"
|
||||
@update="value => answer(value)"
|
||||
>
|
||||
<ListItemInfo
|
||||
:name="$t(prompt.message)"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<VueInput
|
||||
:value="value(prompt.value)"
|
||||
:type="prompt.type === 'password' ? 'password' : 'text'"
|
||||
@input="value => answer(value)"
|
||||
@update="value => answer(value)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="prompt-input">
|
||||
<VueSelect
|
||||
:value="value(prompt.value)"
|
||||
@input="value => answer(value)"
|
||||
@update="value => answer(value)"
|
||||
>
|
||||
<VueSelectButton
|
||||
v-for="(choice, index) of prompt.choices"
|
||||
|
||||
@@ -79,7 +79,7 @@ export default {
|
||||
.group-name
|
||||
padding $padding-item $padding-item ($padding-item / 2)
|
||||
font-size 1.6em
|
||||
font-weight lighter
|
||||
font-weight 300
|
||||
color $vue-ui-color-accent
|
||||
.vue-ui-dark-mode &
|
||||
color lighten($vue-ui-color-accent, 60%)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user