Webpack作为当下最流行的前端构建工具,它可以处理模块化的JavaScript项目,进行代码打包和优化。在Vue项目中,Webpack发挥着不可或缺的作用,它负责分析项目中的依赖图谱,递归地构建bundles,从而实现整个项目的构建。
那么Webpack是如何处理Vue单文件组件的呢?它又是通过哪些具体的步骤实现Vue项目的打包和部署的呢?这是每一个Vue开发者都应该理解和掌握的关键知识点。
当我们使用Vue CLI创建一个Vue项目时,会自动配置Webpack相关的配置。在项目的根目录下会有一个webpack.config.js文件,这就是Webpack的配置文件。
我们来看一下这个配置文件中与Vue相关的主要内容:
// webpack配置
const vueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
// ...省略其他配置
module: {
rules: [
// ... 其他规则
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
// 请确保引入这个插件!
new vueLoaderPlugin()
]
}
vue-loader是Vue单文件组件(SFC)的 Webpack 加载器,它允许你以单文件组件的格式开发 Vue 组件。在 Vue 3 中,vue-loader 封装了 @vue/compiler-sfc,用于预处理单文件组件。我们来看看 vue-loader 的源码是如何工作的。
在vue-loader的源码中,定义了一个 NormalModule 类,这是 webpack 模块中代表一个模块的类。在它的 build 方法中,会调用 this._compile 方法对单文件组件进行加载和解析:
// webpack/lib/NormalModule.js
class NormalModule {
// ...
build(options, compilation, resolver, fs, callback) {
this._compile(options, compilation, resolver, fs, (err, result) => {
// 处理结果...
});
}
_compile(options, compilation, resolver, fs, callback) {
const loaderContext = this.createLoaderContext(resolver, options, fs, compilation);
runLoaders(
{
resource: this.resource,
loaders: this.loaders,
context: loaderContext,
readResource: fs.readFile.bind(fs)
},
(err, result) => {
// 处理结果...
}
);
}
}
在 _compile 中,会调用 runLoaders 方法,执行配置的所有 loader,其中就包含了 vue-loader。
接下来我们看一下 vue-loader 的源码,主要的是 pitch 方法:
// vue-loader/index.js
module.exports.pitch = function(remainingRequest) {
const { loaders, resourcePath, resourceQuery } = this;
const doTransform = !remainingRequest.includes(hotReloadAPIPath);
// 过滤热重载请求
if (doTransform && resourceQuery && resourceQuery.includes('type=script')) {
// 处理