Vue 异步导入与 Webpack

Posted

技术标签:

【中文标题】Vue 异步导入与 Webpack【英文标题】:Vue Async Imports with Webpack 【发布时间】:2018-08-16 05:54:55 【问题描述】:

我有一个 VueJS 2 应用程序,我试图根据配置 JSON 文件中的不同标志加载特定组件。

我的文件结构如下:

root
  config.json
  > src
  >> client
  >>> components
  >>>> dashboard
  >>>>> MenuBarBrand.vue
  > product
  >> product01
  >>> client
  >>>> components
  >>>>> branding
  >>>>>> MenuBrand.vue
  >> product02
  >>> client
  >>>> components
  >>>>> branding
  >>>>>> MenuBrand.vue

目前我尝试了两种不同的方法:

在我的 MenuBarBrand 组件中使用 webpack 导入语法:

<template>
    <b-navbar-brand href="/dashboard">
        <MenuBrand />
    </b-navbar-brand>
</template>

<script>
import config from '../../../../config.json';
const MenuBrand = import(`../../../../product/$config.product/components/branding/MenuBrand`); 

export default 
    name: 'MenuBarBrand',
    components: 
         'MenuBrand',
    ,

</script>

这会导致以下错误:

或 Vue Async Components 本地注册语法:

<template>
    <b-navbar-brand href="/dashboard">
        <MenuBrand />
    </b-navbar-brand>
</template>

<script>
import config from '../../../../config.json';

export default 
    name: 'MenuBarBrand',
    components: 
        'MenuBrand': () => import(`../../../../product/$config.product/components/branding/MenuBrand`)
    ,

</script>

这会导致以下错误:

我是否有任何明显的错误,或者是否需要任何特定的 babel/webpack 插件来启用此功能?

编辑:根据我收到的评论添加我的加载器配置:

module: 
    rules: [
        
            test: /\.vue$/,
            loader: 'vue-loader',
            options: 
                loaders: 
                    scss: [
                        'vue-style-loader',
                        'css-loader',
                        'sass-loader',
                    ],
                    sass: [
                        'vue-style-loader',
                        'css-loader',
                        'sass-loader?indentedSyntax',
                    ],
                ,
            ,
        ,
        
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
        ,
        
            test: /\.(png|jpg|gif|svg)$/,
            loader: 'file-loader',
            options: 
                name: '[name].[ext]?[hash]',
            ,
        ,
        
            test: /\.css$/,
            loader: 'style-loader!css-loader',
        ,
        
            test: /\.(ttf|otf|eot|woff(2)?)(\?[a-z0-9]+)?$/,
            loader: 'file-loader?name=fonts/[name].[ext]',
        ,
    ],
,

【问题讨论】:

"但目前这两个选项似乎都不起作用。"这没有帮助。请描述预期的行为。 预期的行为是,无论哪种情况,导入都会正常工作,并允许我将 Vue 组件加载到应用程序中。相反,我遇到了错误(我将附加到原始问题中)。 【参考方案1】:

我通过另一种方法解决了这个问题。

在 webpack 配置中,我拉入我的产品标志并创建一个路径:

const config = require('./config.json');
const fs = require('fs');
const path = require('path');

const productPath = path.resolve(__dirname, 'product', config.product);

然后我使用这个路径在 webpack 配置中设置一个别名:

resolve: 
    alias: 
        menuBrandingPath: productPath,
    ,
    extensions: ['*', '.js', '.vue', '.json'],
,

然后在我的 Vue 组件中使用此路径来导入正确的组件:

<template>
    <MenuBrand />
</template>

<script>
    import MenuBrand from 'menuBrandingPath/client/components/branding/MenuBrand'; // menuBrandingPath is an alias in the webpack config

    export default 
        name: 'MenuBar',
        components: 
            MenuBrand,
        ,
    
</script>

我故意省略了 fs 的错误检查和我用来使这个示例更容易理解的回退路径。希望它可以帮助某人! :)

【讨论】:

【参考方案2】:

您需要使用 vue-loader webpack 插件来处理 webpack 设置中的 .vue 文件。这将启用() =&gt; import(...) 语法。

module: 
    rules: [
        
            test: /\.vue$/,
            loader: 'vue-loader'
        ,
        (other loaders....)
    ]
,

或者,在原始示例中使用require

<template>
    <b-navbar-brand href="/dashboard">
        <MenuBrand />
    </b-navbar-brand>
</template>

<script>
import config from '../../../../config.json';
const MenuBrand = require(`../../../../product/$config.product/components/branding/MenuBrand`); 

export default 
    name: 'MenuBarBrand',
    components: 
         'MenuBrand',
    ,

</script>

【讨论】:

谢谢约阿希姆!我已将加载程序语法附加到原始帖子中。据我所知,我已经在使用 vue-loader,但是如果有什么我应该改变的,请告诉我! 嗯 - 我的意思是你的 webpack.conf.js 文件中应该有正确的module-entry,这不是你在这里显示的。我将编辑我的帖子以展示我如何做到这一点的示例。此外,所有这些主要是为了启用异步加载,基本上您可能对同步加载感到满意,在这种情况下,您应该能够在第一个示例中使用 require 而不是 import。

以上是关于Vue 异步导入与 Webpack的主要内容,如果未能解决你的问题,请参考以下文章

webpackwebpack.base.conf.js基础配置

Vue掉坑记

Webpackwebpack5 模块联邦(Module Federation)

Webpackwebpack5 模块联邦(Module Federation)实践

Vue2+webpack+node 配置+入门+详解

Vue2+webpack+node 配置+入门+详解