Skip to content
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

feat!: remove url-loader and file-loader in favor of asset modules #6771

Merged
merged 1 commit into from Oct 23, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/guide/build-targets.md
Expand Up @@ -8,7 +8,7 @@ App is the default build target. In this mode:

- `index.html` with asset and resource hints injection
- vendor libraries split into a separate chunk for better caching
- static assets under 4kb are inlined into JavaScript
- static assets under 8KiB are inlined into JavaScript
- static assets in `public` are copied into output directory

## Library
Expand Down
12 changes: 7 additions & 5 deletions docs/guide/html-and-static-assets.md
Expand Up @@ -129,19 +129,21 @@ will be compiled into:
h('img', { attrs: { src: require('./image.png') }})
```

Internally, we use `file-loader` to determine the final file location with version hashes and correct public base paths, and use `url-loader` to conditionally inline assets that are smaller than 4kb, reducing the amount of HTTP requests.
Internally, we configured webpack [Assets Modules](https://webpack.js.org/guides/asset-modules/) to determine the final file location with version hashes and correct public base paths, and conditionally inline assets that are smaller than 8KiB, reducing the amount of HTTP requests.

You can adjust the inline file size limit via [chainWebpack](../config/#chainwebpack). For example, to set the limit to 10kb instead:
You can adjust the inline file size limit via [chainWebpack](../config/#chainwebpack). For example, to set the limit of inline images to 4KiB instead:

``` js
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options, { limit: 10240 }))
.set('parser', {
dataUrlCondition: {
maxSize: 4 * 1024 // 4KiB
}
})
}
}
```
Expand Down
20 changes: 19 additions & 1 deletion docs/migrations/migrate-from-v4.md
Expand Up @@ -93,13 +93,31 @@ The `css.requireModuleExtension` option is removed. If you do need to strip the

No longer supports generating project with `node-sass`. It has been [deprecated](https://sass-lang.com/blog/libsass-is-deprecated#how-do-i-migrate) for a while. Please use the `sass` package instead.

#### Asset Modules

`url-loader` and `file-loader` are removed in favor of [Asset Modules](https://webpack.js.org/guides/asset-modules/). If you want to adjust the size limit of inline image assets, now you need to set the [`Rule.parser.dataUrlCondition.maxSize`](https://webpack.js.org/configuration/module/#ruleparserdataurlcondition) option:

``` js
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('images')
.set('parser', {
dataUrlCondition: {
maxSize: 4 * 1024 // 4KiB
}
})
}
}
```

#### Underlying Loaders and Plugins

* `html-webpack-plugin` is upgraded from v3 to v5. More details are available in the [release announcement of `html-webpack-plugin` v4](https://dev.to/jantimon/html-webpack-plugin-4-has-been-released-125d) and the [full changelog](https://github.com/jantimon/html-webpack-plugin/blob/master/CHANGELOG.md).
* `sass-loader` v7 support is dropped. See the v8 breaking changes at its [changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md#800-2019-08-29).
* `postcss-loader` is upgraded from v3 to v5. Most notably, `PostCSS` options (`plugin` / `syntax` / `parser` / `stringifier`) are moved into the `postcssOptions` field. More details available at the [changelog](https://github.com/webpack-contrib/postcss-loader/blob/master/CHANGELOG.md#400-2020-09-07).
* `copy-webpack-plugin` is upgraded from v5 to v8. If you never customized its config through `config.plugin('copy')`, there should be no user-facing breaking changes. A full list of breaking changes is available at [`copy-webpack-plugin` v6.0.0 changelog](https://github.com/webpack-contrib/copy-webpack-plugin/blob/master/CHANGELOG.md).
* `file-loader` is upgraded from v4 to v6, and `url-loader` from v2 to v4. The `esModule` option is now turned on by default for non-Vue-2 projects. Full changelog available at [`file-loader` changelog](https://github.com/webpack-contrib/file-loader/blob/master/CHANGELOG.md) and [`url-loader` changelog](https://github.com/webpack-contrib/url-loader/blob/master/CHANGELOG.md).
* `terser-webpack-plugin` is upgraded from v2 to v5, using terser 5 and some there are some changes in the options format. See full details in its [changelog](https://github.com/webpack-contrib/terser-webpack-plugin/blob/master/CHANGELOG.md).
* When creating new projects, the default `less-loader` is updated from [v5 to v8](https://github.com/webpack-contrib/less-loader/blob/master/CHANGELOG.md); `less` from [v3 to v4](https://github.com/less/less.js/pull/3573); `sass-loader` from [v8 to v11](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md); `stylus-loader` from [v3 to v5](https://github.com/webpack-contrib/stylus-loader/blob/master/CHANGELOG.md).

Expand Down
2 changes: 1 addition & 1 deletion docs/ru/guide/build-targets.md
Expand Up @@ -8,7 +8,7 @@

- `index.html` с внедрением ресурсов и подсказок для пред-загрузки
- сторонние библиотеки разделяются на отдельные фрагменты для лучшего кэширования
- статические ресурсы менее 4 КБайт будут вставлены инлайн в JavaScript
- статические ресурсы менее 8 КБайт будут вставлены инлайн в JavaScript
- статические ресурсы в `public` будут скопированы в каталог сборки

## Библиотека (Library)
Expand Down
12 changes: 7 additions & 5 deletions docs/ru/guide/html-and-static-assets.md
Expand Up @@ -129,19 +129,21 @@ module.exports = {
h('img', { attrs: { src: require('./image.png') }})
```

Внутри используется `file-loader` для определения конечного расположения файла с хэшем версии и правильный путь относительно корня, а также `url-loader` для инлайн-встраивания ресурсов, чей размер меньше 4 КБайт, чтобы уменьшить количество HTTP-запросов к серверу.
Внутри используется `file-loader` для определения конечного расположения файла с хэшем версии и правильный путь относительно корня, а также `url-loader` для инлайн-встраивания ресурсов, чей размер меньше 8 КБайт, чтобы уменьшить количество HTTP-запросов к серверу.

Изменить размер можно через [chainWebpack](../config/#chainwebpack). Например, чтобы установить лимит в 10 КБайт:
Изменить размер можно через [chainWebpack](../config/#chainwebpack). Например, чтобы установить лимит в 4 КБайт:

```js
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options, { limit: 10240 }))
.set('parser', {
dataUrlCondition: {
maxSize: 4 * 1024 // 4KiB
}
})
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/guide/build-targets.md
Expand Up @@ -8,7 +8,7 @@

- `index.html` 会带有注入的资源和 resource hint
- 第三方库会被分到一个独立包以便更好的缓存
- 小于 4kb 的静态资源会被内联在 JavaScript 中
- 小于 8KiB 的静态资源会被内联在 JavaScript 中
- `public` 中的静态资源会被复制到输出目录中

##
Expand Down
12 changes: 7 additions & 5 deletions docs/zh/guide/html-and-static-assets.md
Expand Up @@ -125,19 +125,21 @@ module.exports = {
h('img', { attrs: { src: require('./image.png') }})
```

在其内部,我们通过 `file-loader` 用版本哈希值和正确的公共基础路径来决定最终的文件路径,再用 `url-loader` 将小于 4kb 的资源内联,以减少 HTTP 请求的数量。
在其内部,我们通过 webpack 的 [Assets Modules](https://webpack.js.org/guides/asset-modules/) 配置,用版本哈希值和正确的公共基础路径来决定最终的文件路径,并将小于 8KiB 的资源内联,以减少 HTTP 请求的数量。

你可以通过 [chainWebpack](../config/#chainwebpack) 调整内联文件的大小限制。例如,下列代码会将其限制设置为 10kb
你可以通过 [chainWebpack](../config/#chainwebpack) 调整内联文件的大小限制。例如,下列代码会将内联图片资源限制设置为 4KiB

``` js
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options, { limit: 10240 }))
.set('parser', {
dataUrlCondition: {
maxSize: 4 * 1024 // 4KiB
}
})
}
}
```
Expand Down
67 changes: 22 additions & 45 deletions packages/@vue/cli-service/lib/config/assets.js
@@ -1,12 +1,6 @@
/** @type {import('@vue/cli-service').ServicePlugin} */
module.exports = (api, options) => {
const getAssetPath = require('../util/getAssetPath')
const getVueMajor = require('../util/getVueMajor')

const inlineLimit = 4096

const vueMajor = getVueMajor(api.getCwd())
const supportsEsModuleAsset = (vueMajor !== 2)

const genAssetSubPath = dir => {
return getAssetPath(
Expand All @@ -15,56 +9,39 @@ module.exports = (api, options) => {
)
}

// TODO: use asset modules for webpack 5
// <https://webpack.js.org/guides/asset-modules/>

const genUrlLoaderOptions = dir => {
return {
limit: inlineLimit,
esModule: supportsEsModuleAsset,
// use explicit fallback to avoid regression in url-loader>=1.1.0
fallback: {
loader: require.resolve('file-loader'),
options: {
name: genAssetSubPath(dir),
esModule: supportsEsModuleAsset
}
}
}
}

api.chainWebpack(webpackConfig => {
webpackConfig.module
.rule('images')
.test(/\.(png|jpe?g|gif|webp|avif)(\?.*)?$/)
.use('url-loader')
.loader(require.resolve('url-loader'))
.options(genUrlLoaderOptions('img'))
.rule('svg')
.test(/\.(svg)(\?.*)?$/)
// do not base64-inline SVGs.
// https://github.com/facebookincubator/create-react-app/pull/1180
.set('type', 'asset/resource')
.set('generator', {
filename: genAssetSubPath('img')
})

// do not base64-inline SVGs.
// https://github.com/facebookincubator/create-react-app/pull/1180
webpackConfig.module
.rule('svg')
.test(/\.(svg)(\?.*)?$/)
.use('file-loader')
.loader(require.resolve('file-loader'))
.options({
name: genAssetSubPath('img'),
esModule: supportsEsModuleAsset
})
.rule('images')
.test(/\.(png|jpe?g|gif|webp|avif)(\?.*)?$/)
.set('type', 'asset')
.set('generator', {
filename: genAssetSubPath('img')
})

webpackConfig.module
.rule('media')
.test(/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/)
.use('url-loader')
.loader(require.resolve('url-loader'))
.options(genUrlLoaderOptions('media'))
.set('type', 'asset')
.set('generator', {
filename: genAssetSubPath('media')
})

webpackConfig.module
.rule('fonts')
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i)
.use('url-loader')
.loader(require.resolve('url-loader'))
.options(genUrlLoaderOptions('fonts'))
.set('type', 'asset')
.set('generator', {
filename: genAssetSubPath('fonts')
})
})
}
2 changes: 0 additions & 2 deletions packages/@vue/cli-service/package.json
Expand Up @@ -53,7 +53,6 @@
"default-gateway": "^6.0.3",
"dotenv": "^10.0.0",
"dotenv-expand": "^5.1.0",
"file-loader": "^6.1.1",
"fs-extra": "^9.1.0",
"globby": "^11.0.2",
"hash-sum": "^2.0.0",
Expand All @@ -72,7 +71,6 @@
"ssri": "^8.0.1",
"terser-webpack-plugin": "^5.1.1",
"thread-loader": "^3.0.0",
"url-loader": "^4.1.1",
"vue-loader": "^16.4.0",
"vue-style-loader": "^4.1.3",
"webpack": "^5.22.0",
Expand Down