各位观众老爷,大家好! 今天咱不开车,来聊聊Vue 3 的一个重要伙伴: @vue/cli
,尤其是它的插件系统和配置管理。 这玩意儿就像Vue项目的“变形金刚”,能根据你的需求变出各种形态。
一、 插件系统:让Vue项目“百变星君”
@vue/cli
的插件系统是它最核心的功能之一。 简单来说,插件就是一些预先写好的代码,可以自动完成项目配置、安装依赖、添加功能等任务。 想象一下,你想要一个支持 TypeScript 的 Vue 项目,不用自己吭哧吭哧地配置,直接装个 @vue/cli-plugin-typescript
插件,它就能帮你搞定一切,是不是很爽?
- 插件的本质
插件本质上就是一个 Node.js 模块,通常导出一个函数。 这个函数接收两个参数:
api
:一个包含各种方法的对象,用于操作项目配置、注册命令、安装依赖等。options
:插件的配置选项,可以在vue.config.js
中设置。
咱们来看一个简单的插件例子:
// my-plugin.js
module.exports = (api, options) => {
// 注册一个命令
api.registerCommand('hello', {
description: '打印一句问候语',
usage: 'vue-cli-service hello',
fn: () => {
console.log('Hello, Vue!');
}
});
// 修改 webpack 配置
api.chainWebpack(config => {
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
// 修改 vue-loader 的配置
options.compilerOptions = {
...options.compilerOptions,
whitespace: 'condense' // 去除多余空格
}
return options
})
});
// 注入 webpack-dev-server 配置
api.configureDevServer(config => {
config.proxy = {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true
}
}
});
// 添加一个 webpack 插件
api.configureWebpack(config => {
config.plugins.push(
new require('webpack').BannerPlugin('Generated by my-plugin')
);
});
// 安装依赖
api.extendPackage({
dependencies: {
'lodash': '^4.17.21'
}
});
};
这个插件做了几件事:
- 注册了一个
hello
命令,运行vue-cli-service hello
就可以在控制台看到 "Hello, Vue!"。 - 修改了 webpack 配置,优化 Vue 组件的编译。
- 配置了 webpack-dev-server,添加了代理。
- 添加了一个 webpack 插件,在打包后的文件中添加 banner。
- 安装了
lodash
依赖。
- 插件的使用
要使用插件,有几种方式:
-
通过 CLI 安装:
vue add my-plugin
这会自动安装插件并将其添加到
package.json
的devDependencies
中。 -
手动安装:
npm install my-plugin --save-dev
然后,在
vue.config.js
中配置插件:// vue.config.js module.exports = { configureWebpack: config => { config.resolve.alias['@'] = path.resolve(__dirname, 'src'); }, pluginOptions: { 'my-plugin': { // 插件的配置选项 } } }
api
对象详解
api
对象是插件的核心,它提供了很多方法来操作项目。 咱们来详细看看一些常用的方法:
方法名 | 描述 |
---|---|
registerCommand |
注册一个命令,可以通过 vue-cli-service <command> 运行。 |
chainWebpack |
修改 webpack 配置。 这是一个链式 API,可以方便地修改 webpack 配置的各个方面。 |
configureWebpack |
直接修改 webpack 配置。 这种方式更灵活,但需要更了解 webpack 配置的结构。 |
configureDevServer |
修改 webpack-dev-server 配置。 |
extendPackage |
修改 package.json 文件。 可以添加依赖、修改 scripts 等。 |
resolve |
解析项目中的路径。 例如,api.resolve('src/components/MyComponent.vue') 会返回 src/components/MyComponent.vue 的绝对路径。 |
hasPlugin |
检查是否安装了某个插件。 |
injectOptions |
将插件的配置选项注入到 vue.config.js 中。 |
onRootDisk |
检查给定的路径是否在根磁盘上。 |
setCwd |
设置当前工作目录。 |
二、 配置管理:让Vue项目井井有条
@vue/cli
提供了一套强大的配置管理系统,让你能够灵活地配置项目的各个方面。 主要的配置文件是 vue.config.js
,它允许你自定义 webpack 配置、 devServer 配置、插件选项等。
vue.config.js
的结构
vue.config.js
是一个 Node.js 模块,导出一个对象。 这个对象包含各种配置选项,例如:
// vue.config.js
module.exports = {
// 项目部署的基础路径
publicPath: '/',
// 输出文件目录
outputDir: 'dist',
// 静态资源目录 (相对于 outputDir 的)
assetsDir: 'static',
// 是否在开发环境下每次保存代码时都启用 eslint 验证
lintOnSave: process.env.NODE_ENV !== 'production',
// 生产环境是否生成 sourceMap 文件
productionSourceMap: false,
// webpack 配置
configureWebpack: config => {
// ...
},
// webpack 链式操作
chainWebpack: config => {
// ...
},
// css 相关配置
css: {
// 是否使用 css 分离插件 ExtractTextPlugin
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// css 预设器配置项
loaderOptions: {
sass: {
// 引入全局样式
prependData: `@import "@/assets/styles/global.scss";`
}
}
},
// webpack-dev-server 相关配置
devServer: {
open: true,
host: 'localhost',
port: 8080,
https: false,
hotOnly: false,
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true
}
},
before: app => {}
},
// 第三方插件配置
pluginOptions: {
// ...
}
}
- 常用的配置选项
咱们来详细看看一些常用的配置选项:
publicPath
: 项目部署的基础路径。 如果你将项目部署到服务器的子目录,例如/my-app/
,则需要将publicPath
设置为/my-app/
。outputDir
: 输出文件目录。 默认情况下,构建后的文件会输出到dist
目录。assetsDir
: 静态资源目录。 静态资源,例如图片、字体等,会输出到assetsDir
指定的目录。lintOnSave
: 是否在开发环境下每次保存代码时都启用 eslint 验证。productionSourceMap
: 生产环境是否生成 sourceMap 文件。 建议在生产环境禁用 sourceMap,以减小文件体积。configureWebpack
: 直接修改 webpack 配置。chainWebpack
: 修改 webpack 配置。 这是一个链式 API,可以方便地修改 webpack 配置的各个方面。css
: css 相关配置。 可以配置是否使用 css 分离插件、开启 CSS source maps、css 预设器配置项等。devServer
: webpack-dev-server 相关配置。 可以配置 host、port、proxy 等。pluginOptions
: 第三方插件配置。
chainWebpack
的妙用
chainWebpack
是一个非常强大的配置选项,它允许你通过链式 API 修改 webpack 配置。 这种方式比直接修改 configureWebpack
更安全、更灵活。
咱们来看一个例子:
// vue.config.js
module.exports = {
chainWebpack: config => {
// 修改 svg loader
config.module
.rule('svg')
.exclude.add(path.resolve(__dirname, 'src/icons')) // 排除 src/icons 目录
.end()
// 添加 svg-sprite-loader
config.module
.rule('icons')
.test(/.svg$/)
.include.add(path.resolve(__dirname, 'src/icons')) // 只包含 src/icons 目录
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
}
}
这个例子修改了 svg loader,使其能够使用 svg-sprite-loader
来处理 src/icons
目录下的 svg 文件。
- 环境变量的使用
在 vue.config.js
中,你可以使用环境变量来动态地配置项目。 例如,你可以根据 NODE_ENV
环境变量来设置不同的配置选项。
// vue.config.js
module.exports = {
publicPath: process.env.NODE_ENV === 'production'
? '/my-app/'
: '/',
devServer: {
proxy: {
'/api': {
target: process.env.API_URL || 'http://localhost:3000',
changeOrigin: true
}
}
}
}
在这个例子中,publicPath
会根据 NODE_ENV
环境变量的值来设置不同的值。 如果 NODE_ENV
是 production
,则 publicPath
设置为 /my-app/
; 否则,设置为 /
。 devServer.proxy
也使用了环境变量 API_URL
来设置代理的目标地址。
三、 插件开发实战:一个简单的主题切换插件
为了更好地理解插件系统,咱们来开发一个简单的主题切换插件。 这个插件允许用户通过命令行来切换项目的主题。
- 插件的结构
创建一个名为 vue-cli-plugin-theme
的目录,并在其中创建以下文件:
vue-cli-plugin-theme/
├── index.js
├── generator.js
└── template/
└── theme.scss
index.js
: 插件的主入口文件。generator.js
: 用于生成项目文件的生成器。template/theme.scss
: 主题的样式文件模板。
index.js
的内容
// index.js
module.exports = (api, options) => {
// 注册一个命令
api.registerCommand('theme', {
description: '切换项目主题',
usage: 'vue-cli-service theme <theme-name>',
args: {
'<theme-name>': '主题名称'
},
fn: async (args) => {
const themeName = args._[0];
if (!themeName) {
console.error('请指定主题名称');
return;
}
// 修改 vue.config.js
api.extendPackage({
vue: {
pluginOptions: {
theme: {
currentTheme: themeName
}
}
}
});
console.log(`已切换到主题:${themeName}`);
}
});
// 修改 webpack 配置
api.chainWebpack(config => {
config.module
.rule('scss')
.oneOf('vue')
.use('sass-loader')
.tap(options => {
options.additionalData = `@import "@/template/theme.scss";`;
return options;
})
});
};
这个插件注册了一个 theme
命令,允许用户通过 vue-cli-service theme <theme-name>
来切换主题。 它还修改了 webpack 配置,将 template/theme.scss
文件引入到所有的 scss 文件中。
generator.js
的内容
// generator.js
module.exports = (api, options, rootOptions) => {
api.render('./template');
};
这个生成器将 template/theme.scss
文件复制到项目的 src
目录下。
template/theme.scss
的内容
// template/theme.scss
$theme-name: "default"; // 默认主题
@if $theme-name == "default" {
body {
background-color: #fff;
color: #333;
}
} @else if $theme-name == "dark" {
body {
background-color: #333;
color: #fff;
}
}
这个文件定义了两个主题: default
和 dark
。
- 插件的使用
首先,将插件安装到项目中:
vue add ./vue-cli-plugin-theme
然后,运行 vue-cli-service theme dark
来切换到 dark 主题。 再次运行 vue-cli-service theme default
来切换回 default 主题。
四、 总结
@vue/cli
的插件系统和配置管理是 Vue 项目开发的重要工具。 插件系统可以让你轻松地扩展项目的功能,而配置管理可以让你灵活地配置项目的各个方面。 掌握这两个工具,可以大大提高你的开发效率。
好了,今天的讲座就到这里。 各位观众老爷,咱们下回再见!