Skip to content

Commit f1807fd

Browse files
authored
Merge pull request #3743 from vuejs/next-minor
3.6
2 parents d853d52 + ff62895 commit f1807fd

File tree

39 files changed

+340
-95
lines changed

39 files changed

+340
-95
lines changed

docs/config/README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,16 @@ Deprecated since Vue CLI 3.3, please use [`publicPath`](#publicPath) instead.
140140

141141
### lintOnSave
142142

143-
- Type: `boolean | 'error'`
143+
- Type: `boolean | 'warning' | 'default' | 'error'`
144144
- Default: `true`
145145

146146
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.
147147

148-
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.
148+
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.
149149

150-
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.
150+
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.
151+
152+
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.
151153

152154
Alternatively, you can configure the overlay to display both warnings and errors:
153155

docs/dev-guide/generator-api.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ Add a message to be printed when the generator exits (after any other standard m
9797
- **Usage**:
9898
Convenience method for generating a JS config file from JSON
9999

100+
## makeJSOnlyValue
101+
102+
- **Arguments**
103+
- `{any} str` - JS expression as a string
104+
105+
- **Usage**:
106+
Turns a string expression into executable JS for .js config files
107+
100108
## injectImports
101109

102110
- **Arguments**

docs/guide/build-targets.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ App is the default build target. In this mode:
1313

1414
## Library
1515

16-
::: tip Note on IE Compatibility
17-
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.
18-
:::
19-
2016
::: tip Note on Vue Dependency
2117
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.
2218
:::

docs/guide/css.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ You can select pre-processors (Sass/Less/Stylus) when creating the project. If y
1212

1313
``` bash
1414
# Sass
15-
npm install -D sass-loader node-sass
15+
npm install -D sass-loader sass
1616

1717
# Less
1818
npm install -D less-loader less
@@ -29,6 +29,14 @@ $color: red;
2929
</style>
3030
```
3131

32+
::: tip A Tip on Sass Performance
33+
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:
34+
```
35+
npm install -D fibers
36+
```
37+
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.
38+
:::
39+
3240
### Automatic imports
3341

3442
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:

packages/@vue/cli-plugin-eslint/index.js

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ module.exports = (api, options) => {
1717
'eslint-loader',
1818
{
1919
'eslint-loader': require('eslint-loader/package.json').version,
20-
'eslint': eslintPkg.version
20+
eslint: eslintPkg.version
2121
},
2222
[
2323
'.eslintrc.js',
@@ -30,7 +30,13 @@ module.exports = (api, options) => {
3030
)
3131

3232
api.chainWebpack(webpackConfig => {
33-
webpackConfig.resolveLoader.modules.prepend(path.join(__dirname, 'node_modules'))
33+
webpackConfig.resolveLoader.modules.prepend(
34+
path.join(__dirname, 'node_modules')
35+
)
36+
37+
const { lintOnSave } = options
38+
const allWarnings = lintOnSave === true || lintOnSave === 'warning'
39+
const allErrors = lintOnSave === 'error'
3440

3541
webpackConfig.module
3642
.rule('eslint')
@@ -46,8 +52,9 @@ module.exports = (api, options) => {
4652
extensions,
4753
cache: true,
4854
cacheIdentifier,
49-
emitWarning: options.lintOnSave !== 'error',
50-
emitError: options.lintOnSave === 'error',
55+
emitWarning: allWarnings,
56+
// only emit errors in production mode.
57+
emitError: allErrors,
5158
eslintPath: resolveModule('eslint', cwd) || require.resolve('eslint'),
5259
formatter:
5360
loadModule('eslint/lib/formatters/codeframe', cwd, true) ||
@@ -56,18 +63,25 @@ module.exports = (api, options) => {
5663
})
5764
}
5865

59-
api.registerCommand('lint', {
60-
description: 'lint and fix source files',
61-
usage: 'vue-cli-service lint [options] [...files]',
62-
options: {
63-
'--format [formatter]': 'specify formatter (default: codeframe)',
64-
'--no-fix': 'do not fix errors or warnings',
65-
'--no-fix-warnings': 'fix errors, but do not fix warnings',
66-
'--max-errors [limit]': 'specify number of errors to make build failed (default: 0)',
67-
'--max-warnings [limit]': 'specify number of warnings to make build failed (default: Infinity)'
66+
api.registerCommand(
67+
'lint',
68+
{
69+
description: 'lint and fix source files',
70+
usage: 'vue-cli-service lint [options] [...files]',
71+
options: {
72+
'--format [formatter]': 'specify formatter (default: codeframe)',
73+
'--no-fix': 'do not fix errors or warnings',
74+
'--no-fix-warnings': 'fix errors, but do not fix warnings',
75+
'--max-errors [limit]':
76+
'specify number of errors to make build failed (default: 0)',
77+
'--max-warnings [limit]':
78+
'specify number of warnings to make build failed (default: Infinity)'
79+
},
80+
details:
81+
'For more options, see https://eslint.org/docs/user-guide/command-line-interface#options'
6882
},
69-
details: 'For more options, see https://eslint.org/docs/user-guide/command-line-interface#options'
70-
}, args => {
71-
require('./lint')(args, api)
72-
})
83+
args => {
84+
require('./lint')(args, api)
85+
}
86+
)
7387
}

packages/@vue/cli-plugin-unit-jest/generator/index.js

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,35 @@ module.exports = (api, _, __, invoking) => {
1111
'@vue/test-utils': '1.0.0-beta.29'
1212
},
1313
jest: {
14-
'moduleFileExtensions': [
14+
moduleFileExtensions: [
1515
'js',
1616
'jsx',
1717
'json',
1818
// tell Jest to handle *.vue files
1919
'vue'
2020
],
21-
'transform': {
21+
transform: {
2222
// process *.vue files with vue-jest
2323
'^.+\\.vue$': 'vue-jest',
24-
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub'
24+
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
25+
'jest-transform-stub'
2526
},
2627
'transformIgnorePatterns': ['/node_modules/'],
2728
// support the same @ -> src alias mapping in source code
28-
'moduleNameMapper': {
29+
moduleNameMapper: {
2930
'^@/(.*)$': '<rootDir>/src/$1'
3031
},
3132
// serializer for snapshots
32-
'snapshotSerializers': [
33-
'jest-serializer-vue'
34-
],
35-
'testMatch': [
33+
snapshotSerializers: ['jest-serializer-vue'],
34+
testMatch: [
3635
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
3736
],
3837
// https://github.com/facebook/jest/issues/6766
39-
'testURL': 'http://localhost/'
38+
testURL: 'http://localhost/',
39+
watchPlugins: [
40+
require.resolve('jest-watch-typeahead/filename'),
41+
require.resolve('jest-watch-typeahead/testname')
42+
]
4043
}
4144
})
4245

@@ -60,9 +63,13 @@ module.exports = (api, _, __, invoking) => {
6063
// Jest's shipped babel-jest still uses babel 6,
6164
// so we cannot use extendPackage which renders babel.config.js.
6265
api.render(files => {
63-
files['.babelrc'] = JSON.stringify({
64-
plugins: ['transform-es2015-modules-commonjs']
65-
}, null, 2)
66+
files['.babelrc'] = JSON.stringify(
67+
{
68+
plugins: ['transform-es2015-modules-commonjs']
69+
},
70+
null,
71+
2
72+
)
6673
})
6774
}
6875
} else {
@@ -74,7 +81,7 @@ module.exports = (api, _, __, invoking) => {
7481
}
7582
}
7683

77-
const applyTS = module.exports.applyTS = (api, invoking) => {
84+
const applyTS = (module.exports.applyTS = (api, invoking) => {
7885
api.extendPackage({
7986
jest: {
8087
moduleFileExtensions: ['ts', 'tsx'],
@@ -119,12 +126,12 @@ const applyTS = module.exports.applyTS = (api, invoking) => {
119126
}
120127
})
121128
}
122-
}
129+
})
123130

124-
const applyESLint = module.exports.applyESLint = api => {
131+
const applyESLint = (module.exports.applyESLint = api => {
125132
api.render(files => {
126133
files['tests/unit/.eslintrc.js'] = api.genJSConfig({
127134
env: { jest: true }
128135
})
129136
})
130-
}
137+
})

packages/@vue/cli-plugin-unit-jest/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"jest": "^23.6.0",
3030
"jest-serializer-vue": "^2.0.2",
3131
"jest-transform-stub": "^2.0.0",
32+
"jest-watch-typeahead": "^0.2.1",
3233
"vue-jest": "^3.0.3"
3334
},
3435
"devDependencies": {

packages/@vue/cli-service/__tests__/buildLib.spec.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,45 @@ test('build as lib with webpackConfiguration depending on target (js)', async ()
132132
const commonContent = await project.read('dist/testLib.common.js')
133133
expect(commonContent).not.toContain(`foo: 'bar'`)
134134
})
135+
136+
test('build as lib with --filename option', async () => {
137+
const project = await create('build-lib-filename-option', defaultPreset)
138+
await project.write('src/main.js', `
139+
export default { foo: 1 }
140+
export const bar = 2
141+
`)
142+
const { stdout } = await project.run('vue-cli-service build --target lib --name testLib --filename test-lib src/main.js')
143+
expect(stdout).toMatch('Build complete.')
144+
145+
expect(project.has('dist/demo.html')).toBe(true)
146+
expect(project.has('dist/test-lib.common.js')).toBe(true)
147+
expect(project.has('dist/test-lib.umd.js')).toBe(true)
148+
expect(project.has('dist/test-lib.umd.min.js')).toBe(true)
149+
150+
const port = await portfinder.getPortPromise()
151+
server = createServer({ root: path.join(project.dir, 'dist') })
152+
153+
await new Promise((resolve, reject) => {
154+
server.listen(port, err => {
155+
if (err) return reject(err)
156+
resolve()
157+
})
158+
})
159+
160+
const launched = await launchPuppeteer(`http://localhost:${port}/demo.html`)
161+
browser = launched.browser
162+
page = launched.page
163+
164+
expect(await page.evaluate(() => {
165+
return window.document.title
166+
})).toBe('testLib demo')
167+
168+
// should expose a module with default and named exports
169+
expect(await page.evaluate(() => {
170+
return window.testLib.default.foo
171+
})).toBe(1)
172+
173+
expect(await page.evaluate(() => {
174+
return window.testLib.bar
175+
})).toBe(2)
176+
})

packages/@vue/cli-service/__tests__/generator.spec.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,4 @@ test('dart sass', async () => {
4343

4444
expect(files['src/App.vue']).toMatch('<style lang="scss">')
4545
expect(pkg).toHaveProperty(['devDependencies', 'sass'])
46-
expect(pkg).toHaveProperty(['devDependencies', 'fibers'])
4746
})

packages/@vue/cli-service/__tests__/multiPage.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ async function makeProjectMultiPage (project) {
1515
index: { entry: 'src/main.js' },
1616
foo: { entry: 'src/foo.js' },
1717
bar: { entry: 'src/bar.js' },
18-
foobar: { entry: 'src/foobar.js' }
18+
foobar: { entry: ['src/foobar.js'] }
1919
},
2020
chainWebpack: config => {
2121
const splitOptions = config.optimization.get('splitChunks')

packages/@vue/cli-service/generator/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ module.exports = (api, options) => {
4646
'sass-loader': '^7.1.0'
4747
},
4848
'dart-sass': {
49-
fibers: '^3.1.1',
5049
sass: '^1.17.2',
5150
'sass-loader': '^7.1.0'
5251
},
Binary file not shown.

packages/@vue/cli-service/lib/commands/build/demo-lib-js.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<meta charset="utf-8">
22
<title><%- htmlWebpackPlugin.options.libName %> demo</title>
3-
<script src="./<%- htmlWebpackPlugin.options.libName %>.umd.js"></script>
3+
<script src="./<%- htmlWebpackPlugin.options.assetsFileName %>.umd.js"></script>
44
<% if (htmlWebpackPlugin.options.cssExtract) { %>
5-
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.libName %>.css">
5+
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.assetsFileName %>.css">
66
<% } %>
77

88
<script>

packages/@vue/cli-service/lib/commands/build/demo-lib.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<meta charset="utf-8">
22
<title><%- htmlWebpackPlugin.options.libName %> demo</title>
33
<script src="https://unpkg.com/vue"></script>
4-
<script src="./<%- htmlWebpackPlugin.options.libName %>.umd.js"></script>
4+
<script src="./<%- htmlWebpackPlugin.options.assetsFileName %>.umd.js"></script>
55
<% if (htmlWebpackPlugin.options.cssExtract) { %>
6-
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.libName %>.css">
6+
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.assetsFileName %>.css">
77
<% } %>
88

99
<div id="app">

packages/@vue/cli-service/lib/commands/build/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module.exports = (api, options) => {
3131
'--target': `app | lib | wc | wc-async (default: ${defaults.target})`,
3232
'--formats': `list of output formats for library builds (default: ${defaults.formats})`,
3333
'--name': `name for lib or web-component mode (default: "name" in package.json or entry filename)`,
34+
'--filename': `file name for output, only usable for 'lib' target (default: value of --name)`,
3435
'--no-clean': `do not remove the dist directory before building the project`,
3536
'--report': `generate report.html to help analyze bundle content`,
3637
'--report-json': 'generate report.json to help analyze bundle content',

packages/@vue/cli-service/lib/commands/build/resolveLibConfig.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const fs = require('fs')
22
const path = require('path')
33

4-
module.exports = (api, { entry, name, formats }, options) => {
4+
module.exports = (api, { entry, name, formats, filename }, options) => {
55
const { log, error } = require('@vue/cli-shared-utils')
66
const abort = msg => {
77
log()
@@ -24,16 +24,26 @@ module.exports = (api, { entry, name, formats }, options) => {
2424
api.service.pkg.name ||
2525
path.basename(entry).replace(/\.(jsx?|vue)$/, '')
2626
)
27-
27+
filename = filename || libName
2828
function genConfig (format, postfix = format, genHTML) {
2929
const config = api.resolveChainableWebpackConfig()
3030

31+
const browserslist = require('browserslist')
32+
const targets = browserslist(undefined, { path: fullEntryPath })
33+
const supportsIE = targets.some(agent => agent.includes('ie'))
34+
35+
const webpack = require('webpack')
36+
config.plugin('need-current-script-polyfill')
37+
.use(webpack.DefinePlugin, [{
38+
'process.env.NEED_CURRENTSCRIPT_POLYFILL': JSON.stringify(supportsIE)
39+
}])
40+
3141
// adjust css output name so they write to the same file
3242
if (config.plugins.has('extract-css')) {
3343
config
3444
.plugin('extract-css')
3545
.tap(args => {
36-
args[0].filename = `${libName}.css`
46+
args[0].filename = `${filename}.css`
3747
return args
3848
})
3949
}
@@ -64,12 +74,13 @@ module.exports = (api, { entry, name, formats }, options) => {
6474
inject: false,
6575
filename: 'demo.html',
6676
libName,
77+
assetsFileName: filename,
6778
cssExtract: config.plugins.has('extract-css')
6879
}])
6980
}
7081

7182
// resolve entry/output
72-
const entryName = `${libName}.${postfix}`
83+
const entryName = `${filename}.${postfix}`
7384
config.resolve
7485
.alias
7586
.set('~entry', fullEntryPath)

0 commit comments

Comments
 (0)