Skip to content

feat!: always inject safari-nomodule-fix as an external script; drop --no-unsafe-inline flag #6422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions docs/guide/browser-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,6 @@ For a Hello World app, the modern bundle is already 16% smaller. In production,
::: tip
`<script type="module">` is loaded [with CORS always enabled](https://jakearchibald.com/2017/es-modules-in-browsers/#always-cors). This means your server must return valid CORS headers such as `Access-Control-Allow-Origin: *`. If you want to fetch the scripts with credentials, set the [crossorigin](../config/#crossorigin) option to `use-credentials`.

Also, modern mode uses an inline script to avoid Safari 10 loading both bundles, so if you are using a strict CSP, you will need to explicitly allow the inline script with:

```
Content-Security-Policy: script-src 'self' 'sha256-4RS22DYeB7U14dra4KcQYxmwt5HkOInieXK1NUMBmQI='
```
:::

::: tip Detecting the Current Mode in Config
Sometimes you may need to change the webpack config only for the legacy build, or only for the modern build.

Expand Down
1 change: 0 additions & 1 deletion docs/guide/cli-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ Options:
--mode specify env mode (default: production)
--dest specify output directory (default: dist)
--modern build app targeting modern browsers with auto fallback
--no-unsafe-inline build app without introducing inline scripts
--target app | lib | wc | wc-async (default: app)
--formats list of output formats for library builds (default: commonjs,umd,umd-min)
--inline-vue include the Vue module in the final bundle of library or web component target
Expand Down
7 changes: 0 additions & 7 deletions docs/zh/guide/browser-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,6 @@ Vue CLI 会产生两个应用的版本:一个现代版的包,面向支持 [E
::: tip 提示
`<script type="module">` [需要配合始终开启的 CORS 进行加载](https://jakearchibald.com/2017/es-modules-in-browsers/#always-cors)。这意味着你的服务器必须返回诸如 `Access-Control-Allow-Origin: *` 的有效的 CORS 头。如果你想要通过认证来获取脚本,可使将 [crossorigin](../config/#crossorigin) 选项设置为 `use-credentials`。

同时,现代浏览器使用一段内联脚本来避免 Safari 10 重复加载脚本包,所以如果你在使用一套严格的 CSP,你需要这样显性地允许内联脚本:

```
Content-Security-Policy: script-src 'self' 'sha256-4RS22DYeB7U14dra4KcQYxmwt5HkOInieXK1NUMBmQI='
```
:::

[autoprefixer]: https://github.com/postcss/autoprefixer
[babel-preset-env]: https://new.babeljs.io/docs/en/next/babel-preset-env.html
[babel-preset-app]: https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/babel-preset-app
Expand Down
12 changes: 3 additions & 9 deletions packages/@vue/cli-service/__tests__/modernMode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,20 +100,14 @@ test('should inject nomodule-fix script when Safari 10 support is required', asy
pkg.browserslist.push('safari > 10')
await project.write('package.json', JSON.stringify(pkg, null, 2))

let { stdout } = await project.run('vue-cli-service build')
let index = await project.read('dist/index.html')
// should inject Safari 10 nomodule fix as an inline script
const { safariFix } = require('../lib/webpack/SafariNomoduleFixPlugin')
expect(index).toMatch(`<script>${safariFix}</script>`)

// `--no-unsafe-inline` option
stdout = (await project.run('vue-cli-service build --no-unsafe-inline')).stdout
const { stdout } = await project.run('vue-cli-service build')
expect(stdout).toMatch('Build complete.')

// should output a separate safari-nomodule-fix bundle
const files = await fs.readdir(path.join(project.dir, 'dist/js'))
expect(files.some(f => /^safari-nomodule-fix\.js$/.test(f))).toBe(true)
const index = await project.read('dist/index.html')
// should contain no inline scripts in the output html
index = await project.read('dist/index.html')
expect(index).not.toMatch(/[^>]\s*<\/script>/)
})

Expand Down
4 changes: 1 addition & 3 deletions packages/@vue/cli-service/lib/commands/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ const defaults = {
clean: true,
target: 'app',
module: true,
formats: 'commonjs,umd,umd-min',
'unsafe-inline': true
formats: 'commonjs,umd,umd-min'
}

const buildModes = {
Expand All @@ -28,7 +27,6 @@ module.exports = (api, options) => {
'--mode': `specify env mode (default: production)`,
'--dest': `specify output directory (default: ${options.outputDir})`,
'--no-module': `build app without generating <script type="module"> chunks for modern browsers`,
'--no-unsafe-inline': `build app without introducing inline scripts`,
'--target': `app | lib | wc | wc-async (default: ${defaults.target})`,
'--inline-vue': 'include the Vue module in the final bundle of library or web component target',
'--formats': `list of output formats for library builds (default: ${defaults.formats})`,
Expand Down
13 changes: 6 additions & 7 deletions packages/@vue/cli-service/lib/commands/build/resolveAppConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@ module.exports = (api, args, options) => {
if (!args.moduleBuild) {
// Inject plugin to extract build stats and write to disk
config
.plugin('modern-mode-legacy')
.use(ModernModePlugin, [{
targetDir,
isModuleBuild: false
}])
.plugin('modern-mode-legacy')
.use(ModernModePlugin, [{
targetDir,
isModernBuild: false
}])
} else {
config
.plugin('safari-nomodule-fix')
.use(SafariNomoduleFixPlugin, [{
unsafeInline: args['unsafe-inline'],
// as we may generate an addition file asset (if `no-unsafe-inline` specified)
// as we may generate an addition file asset (if Safari 10 fix is needed)
// we need to provide the correct directory for that file to place in
jsDirectory: require('../../util/getAssetPath')(options, 'js')
}])
Expand Down