Note:
此篇文章主要是对 Shared Options 中的几个比较难理解的配置选项的理解介绍:
- define
- css
- modules
- preprocessorOptions
- devSourcemap
- postcss
- resolve
- alias
- dedupe
- conditions
- mainFields
- browserField
- extensions
- preserveSymlinks
define:
定义全局常量替换方式。
其中每项在开发环境下会被定义在全局,如:window.<define.key>; 而在构建时被静态替换。
- String 值会以原始表达式形式使用,所以如果定义了一个字符串常量,它需要被显式地打引号。 (例如使用
JSON.stringify
) - 为了与 esbuild 的行为保持一致,表达式必须为一个 JSON 对象(null、boolean、number、string、数组或对象),亦或是一个单独的标识符。
- 替换只会在匹配到周围不是其他字母、数字、
_
或$
时执行。
define: {
__KEY__: value, // value 如果是字符串,需要 JSON.stringify(value)
__KEY_A__: 11
}
// 客户端获取 常来那个的写法
console.log(__KEY__) // ${ JSON.stringify(value) }
console.log(__KEY_A__) // 11
css:
在vite.config.js中我们通过css属性去控制真个vite对于css的处理行为;
css.modules 配置:
modules
的配置最终会给到 postcss-modules, 进行处理; 可参考 postcss-modules
的配置;
-
localConvention
: 修改生成的配置对象的key的展示形式(驼峰还是中划线形式) -
scopeBehaviour
: 配置当前的模块化行为是模块化还是全局化 (有hash就是开启了模块化的一个标志, 因为他可以保证产生不同的hash值来控制我们的样式类名不被覆盖) -
generateScopedName
: 生成的类名的规则(可以配置为函数, 也可以配置成字符串规则: interpolatename -
hashPrefix
: 生成hash会根据你的类名 + 一些其他的字符串(文件名 + 他内部随机生成一个字符串)去进行生成, 如果你想要你生成hash更加的独特一点, 你可以配置hashPrefix, 你配置的这个字符串会参与到最终的hash生成, (hash: 只要你的字符串有一个字不一样, 那么生成的hash就完全不一样, 但是只要你的字符串完全一样, 生成的hash就会一样) -
globalModulePaths
: 代表你不想参与到css模块化的路径.
DEMO
:
css: { // 对 css 的行为进行配置
// modules 的配置最终会给到 postcss-modules(https://github.com/css-modules/postcss-modules), 进行处理; 可参考 postcss-modules 的配置;
modules: { // 配置 css modules 的行为;
// scopeBehaviour:配置当前的模块化行为是模块化还是全局化 (有hash就是开启了模块化的一个标志, 因为他可以保证产生不同的hash值来控制我们的样式类名不被覆盖)
scopeBehaviour: 'local', // 默认:local; 可选: global | local;
// globalModulePaths: 为全局模块定义路径。它是一个用正则表达式定义路径的数组;// 代表你不想参与到css模块化的路径
// globalModulePaths: ['./global/global.module.less'],
globalModulePaths: [/./global/style//],
// generateScopedName: 通过插值字符串的形式,配置参考:interpolatename(https://github.com/webpack/loader-utils#interpolatename)
// generateScopedName: "[name]__[local]___[hash:base64:5]",
// generateScopeName: 通过 callback 函数的形式自定义生成的类名;提供的参数:name(类名)、filename(文件名)、css(css 块)
// generateScopedName: (name, filename, css) => {
// console.log('name -> ', name)
// console.log('filename -> ', filename)
// console.log('css -> ', css)
// const path = require("path");
// const i = css.indexOf("." + name);
// const line = css.substr(0, i).split(/[\r\n]/).length;
// const file = path.basename(filename, ".css");
// return "_" + file + "_" + line + "_" + name;
// },
// hashPrefix: 生成 hash 会根据你的类名 + 一些其他的字符串(文件名 + 它内部随机生成一个字符串)去进行生成, 如果你想要你生成 hash 更加的独特一点, 你可以配置 hashPrefix, 你配置的这个字符串会参与到最终的 hash 生成, (hash: 只要你的字符串有一个字不一样, 那么生成的 hash 就完全不一样, 但是只要你的字符串完全一样, 生成的 hash 就会一样)
hashPrefix: 'prefix',
// localsConvention: 设置导出的样式 classnames 的 json 对象的 key 的展示形式;(驼峰 | 仅驼峰 | 中划线 | 仅中划线);
// 或者根据 originalClassName(原始类名)、generatedClassName(生成的唯一类名)、inputFile(输入类名的文件) 参数自定义类名;
localsConvention: 'camelCaseOnly', // 默认:null; 可选:'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly';
// localsConvention: (originalClassName, generatedClassName, inputFile) => {
// console.log('originalClassName -> ', originalClassName)
// console.log('generatedClassName -> ', generatedClassName)
// console.log('inputFile -> ', inputFile)
// return 'test'
// },
},
}
css.preprocessorOptions 配置:
配置传递给对应的 css 预处理器的参数;
参数配置,参考各预处理的的配置项;如 less options ;
DEMO
:
css: {
// preprocessorOptions: 指定传递给 CSS 预处理器的选项; key + config, key 代表预处理器的名;
preprocessorOptions: {
// 整个的配置对象都会最终给到 less的执行参数(全局参数)中去,相当于 webpack 中给 less-loader 传递配置参数;
less: {
math: 'always', // 较少进行数学计算,兼容跟多数学计算的写法;
globalVars: { // 配置 less 的全局变量
mainColor: 'yellow'
}
}
}
}
css.devSourcemap 配置:
在开发过程中是否启用 sourcemap。
DEMO:
css: {
devSourcemap: true, // 开启 css 的sourceMap(文件索引)
}
css.postcss 配置:
官方文档记录:
类型: string | (postcss.ProcessOptions & { plugins?: postcss.AcceptedPlugin[] })
-
内联的 PostCSS 配置(格式同 postcss.config.js), 或者一个(默认基于项目根目录的)自定义的 PostCSS 配置路径。
-
对内联的 POSTCSS 配置,它期望接收与
postcss.config.js
一致的格式。但对于plugins
属性有些特别,只接收使用 数组格式。 -
搜索是使用 postcss-load-config 完成的,只有被支持的文件名才会被加载。如:
->
.postcssrc.js
->.postcssrc.mjs
->.postcssrc.cjs
->.postcssrc.ts
->postcss.config.js
->postcss.config.mjs
->postcss.config.cjs
->postcss.config.ts
-
【注意】:
-
如果提供了该内联配置,
Vite
将不会搜索其他PostCSS
配置源。 -
vite
已经内置了postcss
, 一般无需再次安装postcss
, 直接使用,安装插件即可,不排除由于对版本的要求要重新安装postcss
; -
postcss
功能非常强大,如,css
语法降级、css
属性前缀补全 等功能, 这些功能 less/sass/stylus 等预处理器并没有实现,postcss
可以通过css
插件解决这些问题;而且它还可以通过各种css
插件解决各种css
处理问题;
DEMO:
// vite.config.js
import { defineConfig } from 'vite';
const path = require('path');
const postcssGlobalData = require('@csstools/postcss-global-data');
const postcssPresetEnv = require('postcss-preset-env');
export default defineConfig({
css: { // 对 css 的行为进行配置
// postcss: 配置postcss相关;使用此属性,postcss.config.js 文件会失效;所以只能二选一;
postcss: {
plugins: [
postcssGlobalData({
files: [
path.resolve(__dirname, 'global/style/variable.css')
]
}),
postcssPresetEnv({
features: {
'custom-properties': { preserve: true }
}
})
]
},
}
})
一般我们会把 postcss 的配置放在 postcss.config.js 中单独设置,如下:
// postcss.config.js
const postcssPresetEnv = require('postcss-preset-env');
const postcssGlobalData = require('@csstools/postcss-global-data');
const path = require('path')
module.exports = {
plugins: [
postcssGlobalData({
files: [
path.resolve(__dirname, 'global/style/variable.css')
]
}),
postcssPresetEnv({
features: {
'custom-properties': { preserve: true }
}
})
]
}
resolve:
resolve.alias 配置:
官网摘录:
- 将会被传递到
@rollup/plugin-alias
作为 entries 的选项。也可以是一个对象,或一个{ find, replacement, customResolver }
的数组。 - 当使用文件系统路径的别名时,请始终使用绝对路径。相对路径的别名值会原封不动地被使用,因此无法被正常解析。
NOTE:
- 重命名的路径不应该以 ‘/’ 结尾
DEMO:
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@assets': path.resolve(__dirname, './src/assets'),
}
}
resolve.dedupe 配置:
官网摘录:
如果你在你的应用程序中有相同依赖的副本(比如 monorepos
),请使用此选项强制 Vite
始终将列出的依赖项解析为同一副本(从项目根目录)。
理解:
将此 dedupe
设置中的库名,经过检索,只取一个版本的库(最外层的根库);
DEMO:
resolve: {
dedupe: ['@babel/core', '@babel/parser', '@x/a', '@x/b']
}
// 这样就强制使用 @babel 和 @x 库
resolve.conditions 配置:
解决程序包中 情景导出 时的其他允许条件。
一个带有情景导出的包可能在它的 package.json
中有以下 exports
字段:
{
"exports": {
".": {
"import": "./index.esm.js",
"require": "./index.cjs.js"
}
}
}
vite
默认允许的情景:import
, module
, browser
, default
, 和基于当前的情景为 production
或 development
;
resolve.conditions
配置项可以指定其它允许的情景;
Demo:
项目 test-vite
里,安装了 foo
包,如图:
package.json
中 exports
提供了几种情景引入的方式,如下:
// package.json
"exports": {
".": {
"x": "./index-x.js",
"y": "./index-y.js",
"node": "./index-node.js",
"import": "./index-import.js",
"require": "./index-require.js",
"default": "./index-import.js"
},
"./xx": {
"x": "./index-x.js",
"y": "./index-y.js"
}
}
项目的 test-vite
的 vite.config.js
中设置 resolve.conditions
, 如下:
import { defineConfig } from 'vite';
export default defineConfig(() => {
return {
resolve: {
conditions: ['y']
}
}
})
test-vite
中导入 foo
包:
import foo from 'foo'; // 这时导入的就是 index-y.js
imort foo from 'foo/xx'; // 这时导入的是 index-y.js
[NOTE]
: 这在 monorepo 库的应用会更适合一点;
resolve.mainFields 配置:
官网摘录:
- 类型:
string[]
- 默认:
['module', 'jsnext:main', 'jsnext']
package.json
中,在解析包的入口点时尝试的字段列表。注意:这比从 exports
字段解析的情景导出优先级低:如果一个入口点从 exports
成功解析,resolve.mainFields
将被忽略。
resolve.extensions 配置:
官网摘录:
- 类型:
string[]
- 默认:
['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json']
导入时想要省略的扩展名列表。注意,不 建议忽略自定义导入类型的扩展名(例如:.vue
),因为它会影响 IDE 和类型支持。
resolve.preserveSymLinks 配置:
官网摘录:
- 类型:
boolean
- 默认:
false
启用此选项会使 Vite 通过原始文件路径(即不跟随符号链接的路径)而不是真正的文件路径(即跟随符号链接后的路径)确定文件身份。
DEMO:
// vite.config.js
resolve: {
preserveSymlinks: true
}
test-vite
项目 npm link [my-test-module]
, my-test-module
是自开发模块包,preserveSymLinks
在 true
和 false
时,导入路径对比,如下:
// preserveSymlinks: false 时
import myTestModule from '/@fs/Users/xxx/xxx/.../my-test-module/index.js';
// preserveSymlinks: true 时
import myTestModule from '/node_modules/.vite/deps/my-test-module.js?v=b98ad576';