Как обновить несколько связанных js файлов с помощью веб-пакета? - PullRequest
3 голосов
/ 02 февраля 2020

У меня есть простое приложение, в котором пользователь должен предоставить определенную информацию следующим образом.

  1. Пожалуйста, укажите свой домен.

    Пользователь: www.google.com

  2. Пожалуйста, укажите ваш обширный URL.

    пользователь: www.vast.xx.com

  3. Пожалуйста, выберите позицию. а) Снизу слева. б) справа внизу.

    пользователь: б) справа внизу

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

 (function (w,d,s,o,f,js,fjs) {
            w['JS-Widget']=o;w[o] = w[o] || function () { (w[o].q = w[o].q || []).push(arguments) };
            js = d.createElement(s), fjs = d.getElementsByTagName(s)[0];
            js.id = o; js.src = f; js.async = 1; fjs.parentNode.insertBefore(js, fjs);
        }(window, document, 'script', 'mw', 'www.mywebisite.com/widget123.js'));
        mw('init', { someConfiguration: 448 });
        mw('message', 'x');
    </script>

Вот мой полный файл конфигурации веб-пакета: конфигурация веб-пакета С помощью этого сценария пользователь может использовать его на своем веб-сайте, что важно отметить здесь это www.mywebisite.com/widget123.js это связанный js файл, сгенерированный webpack следующим образом.

Вот часть моего кода, который я использую для генерации связанных js файлов с использованием webpack с помощью команды npm run build

const HtmlWebpackPlugin = require('html-webpack-plugin');
// ...
return [{
  entry: './src/main.js',
  plugins: [
    new HtmlWebpackPlugin({ title: 'Caching' }),
  ],
  output: {
    **filename: 'widget.[contenthash].js',**
    path: path.resolve(bundleOutputDir),
  }
}]

Для создания связанного файла js каждый раз, когда пользователь генерирует новый код, мне нужно запустить npm run build, чтобы сделать это, я использую WebSockets для отправки команды на сервер следующим образом.

HTML (client)

    <html>
    <body>
     <button onClick="sendCommands()"> Generate Code</button>
    </body>
    <script>

    const ws = new WebSocket('ws://localhost:9898/');
   function sendCommands(){
    ws.onopen = function() {
        console.log('WebSocket Client Connected');
        ws.send('npm run build');
    };
   } 
    ws.onmessage = function(e) {
      console.log("Received: '" + e.data + "'");
    };

    </script>
    </html>

Вот сервер. js

const http = require('http');
const WebSocketServer = require('websocket').server;
const util = require('util');
const exec = util.promisify(require('child_process').exec);

const server = http.createServer();
server.listen(9898);

const wsServer = new WebSocketServer({
    httpServer: server
});

wsServer.on('request', function(request) {
    const connection = request.accept(null, request.origin);

    connection.on('message', function(message) {
      console.log(message.utf8Data);
      const { stdout, stderr } = await exec(message.utf8Data);
      console.log('stdout:', stdout);
      console.log('stderr:', stderr);
      connection.sendUTF('Hi this is WebSocket server!');
    });
    connection.on('close', function(reasonCode, description) {
        console.log('Client has disconnected.');
    });
});

Проблема:

Теперь предположим, что у меня есть 4 пользователя, в каждом из которых Я сгенерировал свой собственный js файл комплекта в папке dist. У меня будет четыре таких файла: widget4321.js, widget3345.js, widget1123.js, widget4321.js

Предположим, я изменил цвет своего виджета. Как мне обновить эти файлы с помощью веб-пакета? ?.

Примечание: пожалуйста, предоставьте другое решение Если у вас есть одна благодарность.

Ответы [ 2 ]

3 голосов
/ 05 февраля 2020

Возможно, вам будет проще иметь один файл виджета (созданный вами с конфигурацией по умолчанию) и использовать предоставленную пользователем информацию в качестве параметров.

имя_домена: www.google.com vastUrl: www.vast.xx.com позиция: внизу справа

 (function (w,d,s,o,f,js,fjs) {
            w['JS-Widget']=o;w[o] = w[o] || function () { (w[o].q = w[o].q || []).push(arguments) };
            js = d.createElement(s), fjs = d.getElementsByTagName(s)[0];
            js.id = o; js.src = f; js.async = 1; fjs.parentNode.insertBefore(js, fjs);
        }(window, document, 'script', 'mw', 'www.mywebisite.com/widget123.js'));
        mw('init', { 
                       someConfiguration: 448, 
                       domainName: 'www.google.com', 
                       vastUrl: 'www.vast.xx.com', 
                       position: 'bottom right'
                    });
        mw('message', 'x');
    </script>

После этого используйте переменные в вашем виджете.

Затем обновление цвета виджета повлияет на все установленные виджеты и сохранит конфигурацию пользователя.

1 голос
/ 06 февраля 2020

Поскольку вы используете 'widget.[contenthash].js' содержимое га sh, и оно будет меняться при каждом изменении содержимого файла, поэтому вы не можете связать файл с пользователем

Вместо этого можно использовать contenthash вы могли бы сделать что-то вроде этого

{
  output {
    filename: `widget.${someUserSpecificId}.js`
    ...
    ...
  }
}

Теперь вопрос в том, как вы сможете передать someUserSpecificId в конфигурации. Для этого вы можете использовать environment-options Webpack

теперь в конфигурации webpack, если вы экспортируете функцию вместо объекта, подобного этому

function (env, arg) {
  return {
    ...
    ...
    output: {
      filename: `widget.${env.someUserSpecificId}.js`
      ...
      ...
  }
}

, и теперь вы можете передать env.someUserSpecificId с опцией cli, такой как

 webpack --env.someUserSpecificId=foo

, теперь вы можете обновить любой пакет для любого пользователя, как вам нравится

ПРИМЕЧАНИЕ Имейте в виду, что вы не используете фактический идентификатор пользователя в имени файла, потому что он будет предоставлен клиенту, вместо этого создайте некоторый случайный идентификатор для каждого пользователя, который можно показывать на клиенте и уникальный для каждого пользователя


UPDATE метод выше Описанное полезно для обновления некоторого указанного c пакета, но если вы хотите обновить весь пакет в одном go, вам нужно немного настроить логи c

вместо передачи someUserSpecificId из аргумент командной строки вы можете сделать это

const usersIdArray = ['userId1', 'userId2', ...otherUsersId];

const webpackConfig = userIdArray.map(someUserSpecificId => {
  return {
    ...
    ...
    output: {
      filename: `widget.${someUserSpecificId}.js`
      ...
      ...
    }
  };
});

module.exports = webpackConfig;

то, что он сделает, это даст вам массив с несколькими конфигурациями webpack, и вы можете передать этот массив непосредственно в webpack, и webpack обновит все файлы согласно ng к соответствующей конфигурации см. экспорт нескольких конфигураций

Примечание , если у вас очень большой массив пользователей, пожалуйста, пакетируйте свою задачу в небольшом сегменте

Другая идея оптимизации , поскольку вы запускаете эту задачу на своем сервере, было бы неплохо подумать о какой-то оптимизации, чтобы уменьшить количество повторяющихся задач. Одна из идей, которые у меня есть сейчас, заключается в том, что вы можете собирать пакеты из двух частей 1. будет содержать пользовательские данные c config 2. будет содержать ваш код

, поэтому, если пользователь изменит свою конфигурацию, вы должны собрать только эту часть, а если вы измените свою конфигурацию, то вы также должны собрать ее только один раз, потому что ваш общий код будет таким же для всех пользователей (например, тема)

и при создании окончательного пакета просто объедините пользовательскую c конфигурацию с вашим кодом, чтобы уменьшить количество повторяющихся задач, и это будет намного быстрее

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...