chore: merge branch 'dev' into docs [ci skip]

This commit is contained in:
Haoqun Jiang
2019-04-14 00:41:50 +08:00
138 changed files with 3322 additions and 1854 deletions
+3
View File
@@ -8,6 +8,9 @@ module.exports = {
env: {
"jest": true
},
globals: {
name: 'off'
},
rules: {
"indent": ["error", 2, {
"MemberExpression": "off"
+1
View File
@@ -8,3 +8,4 @@ temp
.vuerc
.version
.versions
.changelog
+123
View File
@@ -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
+5 -3
View File
@@ -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:
+8
View File
@@ -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**
-4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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"
}
}
+1 -1
View File
@@ -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'))
})
+4 -1
View File
@@ -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 = []
}
+7 -5
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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'
}
})
}
+5 -4
View File
@@ -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'
+31 -17
View File
@@ -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)
}
)
}
+3 -3
View File
@@ -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": {
+2 -2
View File
@@ -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"
}
+1 -1
View File
@@ -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')
+2 -3
View File
@@ -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 {
+2 -1
View File
@@ -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))
+15 -4
View File
@@ -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
+12 -5
View File
@@ -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
}
})
}
+26 -23
View File
@@ -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"
}
+46
View File
@@ -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'
+3 -3
View File
@@ -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": {
+2 -2
View File
@@ -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)
+6 -1
View File
@@ -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
+13 -3
View File
@@ -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'
}
+2 -20
View File
@@ -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
+24 -8
View File
@@ -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",
+30 -26
View File
@@ -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