Как я могу поделиться библиотекой между моим Vue CLI-приложением и существующим vanilla JavaScript? - PullRequest
4 голосов
/ 28 апреля 2020

Я работаю над сайтом WordPress, который использует библиотеку Swiper на нескольких страницах в качестве зависимости npm. На веб-сайте есть встроенное приложение Vue CLI 4, к которому я также хотел бы добавить библиотеку Swiper. В настоящее время веб-сайт имеет свою собственную конфигурацию веб-пакета, в то время как приложение использует слегка измененную версию своей конфигурации сборки по умолчанию.

Существуют Vue компоненты Swiper, которые я мог бы использовать, но, как Я уже использую оригинальную библиотеку, я хотел бы избежать дублирования. Я предполагаю, что мне нужно как-то объединить два процесса сборки (если нет другого решения), но я не пытался ничего подобного раньше.

Основная конфигурация веб-пакета выглядит следующим образом:

const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = (env, options) => {
    return {
        entry: {
            main: ["./src/js/index.js", "./src/scss/index.scss"],
            admin: ["./src/scss/admin.scss", "./src/js/admin/index.js"]
        },
        output: {
            path: path.resolve(__dirname, "dist"),
            filename: "[name].js",
            publicPath: "/dist"
        },
        module: {
            rules: [
                {
                    test: /\.js$/,
                    use: {
                        loader: "babel-loader",
                        options: { presets: ["@babel/preset-env"] }
                    }
                },
                {
                    test: /\.scss$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        "css-loader",
                        "sass-loader"
                    ]
                },
                {
                    test: /\.svg$/,
                    use: {
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]',
                            outputPath: '/images',
                            publicPath(url) {
                                return `/wp-content/themes/themename/dist/images/${url}`
                            },
                        },
                    }
                },
            ]
        },
        plugins: [
            new MiniCssExtractPlugin({
                filename: "[name].css"
            })
        ]
    }
};

И структура каталогов:

├── app
|   ├── src
|   ├── dist
|   ├── ...
|   └── vue.config.js
├── src
├── dist
├── ...
└── webpack.config.js

В идеале, я хотел бы сохранить каталоги такими, какие они есть, так как бы я мог использовать Swiper в обоих проектах, не дублируя его обе связки?

Ответы [ 2 ]

4 голосов
/ 01 мая 2020

Просто добавьте все зависимости через NPM для включения в комплект поставщика сборки.

Затем можно использовать vanilla JS, как указано здесь :

// Either Vanilla JavaScript
window.addEventListener('load', function() {
  console.debug('All assets are loaded');
})
// or jQuery
$(document).ready(function() {
  // After App class declared in global namespace
  App.init();
});
// Loaded in document head
<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) {
    // After App class declared in global namespace
    App.init();
  }); 
</script>

Я бы посоветовал использовать или узнать о Vue шаблоне загруженного CLI-проекта с добавленными плагинами CLI через веб-пакет и NPM. Затем в файле vue.config.js вы можете настроить параметры вашего плагина webpack.

Например, используя плагин Webpack Bundle Analyzer, который будет запускаться в качестве вашей сборки с помощью команды сценария npm. С параметром -o он открывает визуализированную карту размера пакета ваших скриптов вендора на карте блоков.

РЕДАКТИРОВАТЬ: Таким образом, в вашем vue.config.js вы можете добавить отдельные точки входа:

module.exports = {
  pages: {
    app: {
      index: 'client/src/index.ts',
      template: 'client/public/index.html',
    },
    main: {
      entry: 'client/src/main.ts',
      template: 'client/public/main.html',
    },
  },
};

Тогда index.html вы можете, например, динамически проверить, есть ли какое-то правило, то есть идентификатор активной сессии в локальном хранилище, и на основе этого метода Intel Init init для вашего приложения.

Тогда у вас будет main.ts, который запускается напрямую приложение, когда пользователь просматривает путь /main в вашем домене.

1 голос
/ 02 мая 2020

Если вы хотите, чтобы Vue использовал библиотеку, которая уже загружена в объект окна, укажите ее в vue.config.js:

module.exports = {
  chainWebpack: config => {
    config.externals({
      swiper: 'Swiper'
    })
  }
}

Теперь везде, где вы используете import Swiper from 'swiper' (или import * as Swiper from 'swiper' - в зависимости от вашего tsconfig и от того, как экспортируется используемая вами библиотека) вы на самом деле получаете то, что в данный момент window.Swiper, независимо от того, какой импорт создается, например (может быть приложением или может быть во время загрузки отложенного загруженного компонента). ).


Что касается авторитетных источников go, я считаю, что высшими авторитетами по этому вопросу являются:

внешние данные

Запретить связывание определенных импортированных пакетов и вместо этого получить эти внешние зависимости во время выполнения.


Также обратите внимание, что вы должны импортировать модуль в public/index.html, используя <script> (указывая, куда вы загружаете эту библиотеку из производства), если вы хотите, чтобы ваш serve работал, как вы сказали веб-пакету, что он найдет эту зависимость в объекте окна. В противном случае ваш build будет работать нормально (при условии, что window.Swiper существует в производстве), но serve не будет.


Использование внешних ссылок с машинописью:

Обратите внимание, что вам все равно понадобится @types/${moduleName} в devDependencies, если вы хотите, чтобы ${moduleName} было напечатано в вашем приложении, если существует @types/${moduleName}.

Если этого не произойдет, вы можете импортировать типы из пакета (в devDependecies, только для типов, он не будет включен в комплект). Если ни одна из этих опций не подходит для вашего конкретного пакета, вы, вероятно, захотите объявить фиктивный модуль в вашем shims-vue.d.ts:

declare module '${moduleName}';

..., который фактически отключит проверку набора текста для этого модуля. Обратите внимание, что объявление макета может иметь пагубные последствия, поскольку оно переопределит любые существующие типы для этого модуля. Поэтому используйте его только тогда, когда ничего не работает.

Очевидно, в вашем случае ${moduleName} равно swagger.

...