【问题标题】:Webpack using wrong node_modules folderWebpack 使用错误的 node_modules 文件夹
【发布时间】:2019-10-20 17:19:24
【问题描述】:

我有一个使用 vue 库项目的 vue 客户端项目(vue 库项目也使用了一些 3rd 方包,如 vue-material)。

它们通过客户端项目的 Package.json 链接,如下所示 "lib": "file:../lib",我正在使用 import Comp from "lib/src/components/Comp"; 在客户端项目中导入组件

问题是当我使用 Webpack 构建客户端项目时,我的库中的文件使用 lib/node_modules/vue 而不是 node_modules/vue,这会导致双重 vue 实例化。

任何人都知道为什么当我从客户端文件夹使用 webpack 构建时,它会在我的库文件夹中查找 vue 包?有没有办法解决这个问题?

我的 webpack.config

"use strict";
const path = require("path");
const utils = require("./utils");
const config = require("../config");
const vueLoaderConfig = require("./vue-loader.conf");

function resolve(dir) {
  return path.join(__dirname, "..", dir);
}

module.exports = {
  entry: {
    app: ["babel-polyfill", "./src/main.js"]
  },
  output: {
    path: config.build.assetsRoot,
    filename: "[name].js",
    publicPath: process.env.NODE_ENV === "production" ? config.build.assetsPublicPath : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: [".js", ".vue", ".json"],
    alias: {
      vue$: "vue/dist/vue.esm.js",
      "@": resolve("src"),
      src: resolve("src"),
      assets: resolve("src/assets"),
      components: resolve("src/components"),
      utilities: resolve("src/utilities"),
      directives: resolve("src/directives"),
      plugins: resolve("src/plugins"),
      data: resolve("src/data"),
      "vuex-store": resolve("src/store"),
      "lib": resolve("node_modules/lib")
    }
  },
  module: {
    rules: [
      {
        test: /\.(js|vue)$/,
        loader: "eslint-loader",
        enforce: "pre",
        include: [resolve("src")],
        options: {
          formatter: require("eslint-friendly-formatter")
        }
      },
      {
        test: /\.vue$/,
        loader: "vue-loader",
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: "babel-loader",
        include: [resolve("src"), resolve("../lib/src")]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: "url-loader",
        options: {
          limit: 10000,
          name: utils.assetsPath("img/[name].[hash:7].[ext]")
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: "url-loader",
        options: {
          limit: 10000,
          name: utils.assetsPath("media/[name].[hash:7].[ext]")
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: "base64-font-loader",
        options: {
          limit: 10000,
          name: utils.assetsPath("fonts/[name].[hash:7].[ext]")
        }
      },
      {
        test: /\.ico$/,
        loader: "file-loader?name=[name].[ext]"
      }
    ]
  }
};

我的客户的主要入口

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.

// Core Imports
import Vue from 'vue'
import App from './App'

// Plugins
import { ComponentsPlugin } from "lib/src/components";

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
})

【问题讨论】:

  • 你能把webpack.config.js和你使用导入的相关代码贴出来吗?
  • 好的,我发布了我的配置文件
  • 我认为webpack.config.sj 上的这条线"lib": resolve("node_modules/lib") 会导致问题。我不知道 vue 库(你的?第 3 方?)建议:a。如果您将 lib 移动到您的 src 并删除 lib 别名 b。使用require("src/components")index.js 添加到node_modules\lib 文件夹中

标签: vue.js npm webpack vuejs2


【解决方案1】:

当我没有解决这个问题时,我决定调试 webpack 的编译器。

似乎 webpack 使用了一个名为“enhanced-resolve”的库(我们实际上在 webpack 的 resolve:{} 部分中将参数发送到该库)。使用resolve.alias 属性,我们可以将任何require 重定向到我们想要的任何文件夹。

因此,要将任何require("vue") 重定向到我自己的 vue.esm.js,我只需要添加这样的条目(我最初有该行,但它指向的是相对路径而不是绝对路径):

resolve: {
  alias: {
    vue$: resolve("node_modules/vue/dist/vue.esm.js"),
  }
}

注意库名称末尾的 $,它表示增强解析包只有 1 个模块,因此任何名称为“vue”或“vue”子目录的要求都应使用别名解析.

Enhanced-Resolve - ResolverFactory.js

if(/\$$/.test(alias)) {
    onlyModule = true;
    ....
}

Enhanced-Resolve - AliasPlugin.js

// InnerRequest is the path (vue/dist/vue.esm.js)
// name is the alias name without the $ (vue)
if(innerRequest === name || (!onlyModule && startsWith(innerRequest, name + "/"))) {
    continue resolving....
}

【讨论】:

    猜你喜欢
    • 2016-12-09
    • 2019-01-08
    • 2021-02-13
    • 2018-06-01
    • 2018-11-28
    • 2019-11-14
    • 2019-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多