Webpack использует неправильную папку node_modules - PullRequest
0 голосов
/ 20 октября 2019

У меня есть проект клиента vue, в котором используется проект библиотеки vue (в проекте библиотеки vue также используются некоторые сторонние пакеты, такие как vue-material).

Они связаны через пакет Package.json проекта клиента, напримерэто "lib": "file:../lib", и я импортирую компоненты в клиентский проект, используя import Comp from "lib/src/components/Comp";

Проблема заключается в том, что при создании клиентского проекта с использованием Webpack файлы в моей библиотеке используют lib/node_modules/vue вместо node_modules/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 }
})

1 Ответ

0 голосов
/ 21 октября 2019

Поскольку у меня закончились решения этой проблемы, я решил отладить компилятор веб-пакета.

Кажется, в веб-пакете используется библиотека с именем 'extended-resolve' (мы фактически отправляем параметры этой библиотеке в нашем веб-пакете * 1003). * раздел). И используя свойство 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....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...