тег сценария рендеринга сервера вне сборки webpack

Я использую сервер для моего приложения-приложения следующим образом:

export default ({ clientStats }: { clientStats: any }) => async (req: Request, res: Response, next: any) => {
  const context: any = {};

  const app = (
    <StaticRouter location={req.url} context={context}>
      <Application />
    </StaticRouter>
  );

  if (context.url) {
    res.writeHead(301, {
      Location: context.url
    });

    res.end();
    return;
  }

  const { styles, js, scripts } = flushChunks(clientStats, {
    chunkNames: flushChunkNames()
  });

  const appString = renderToString(app);
  const { title } = Helmet.renderStatic();

  res.status(200).send('
    <!doctype html>
    <html lang="en">
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        ${styles}
        ${title}
      </head>
      <body>
        <div id="root">${appString}</div>
        <script type=\'text/javascript\' src=\'init.js\' defer></script>
      </body>
    </html>
');
};

Как я могу ссылаться на скрипт, который находится за пределами сборки webpack?

У меня есть файл init.js, который очень мало, и я хочу просто ссылаться на него.

Где я могу выразить это так, что когда html визуализируется, тег скрипта разрешается?

Ответ 1

Это так просто, но немного сложно, сначала я объясню весь подход, а затем покажу в коде.

Вы должны рассмотреть папку для всех файлов JavaScript из которой они webpack сборки webpack. Затем поместите их в эту папку, а затем импортируйте их как externals в конфигурацию webpack. затем установите его как отдельный файл поставщика, и абсолютное имя выходного файла должно быть динамически, поэтому webpack строить свой пакет, а затем скопировать ваш файл JavaScript в папку dist. следуйте ниже:

// webpack.config.js
...
module.exports = {
    ...
    externals: {
        separateFile: '${srcRoot}/outFiles/yourJavaScriptFile.js',
    },
    ...
};

Используя приведенный выше код, вы рассматриваете папку для вашего файла JavaScirpt и импортируете ее в конфигурацию webpack как конфигурацию externals.

Теперь вы должны импортировать его как отдельный файл вместе с файлами приложений. увидеть ниже:

// webpack.config.js
...
module.exports = {
    ...
    entry: {
        myFile: 'separateFile', // <== its your external imported file
        app: '${srcRoot}/app/index.js', // <== its your app file
    },
    output: {
        path: '/dist',
        filename: '[name].js' // <== dynamically make your JavaScript files,
                              //      so, in dist folder you can see app.js and
                              //      myFile.js file
    }
    ...
};

Определенно, вы должны импортировать эти файлы в свою функцию шаблона, следовательно:

  ...
  res.status(200).send('
    <!doctype html>
    <html lang="en">
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        ${styles}
        ${title}
      </head>
      <body>
        <div id="root">${appString}</div>
        <script src="app.js" defer></script>
        <script src="myFile.js" defer></script>
      </body>
    </html>
 ');
...

Ответ 2

Вы должны сделать init.js доступным в корне вашей сборки проекта, поэтому сервер будет использовать его при рендеринге вашего файла, вы можете увидеть пример здесь: https://github.com/webpack/webpack.js.org/blob/rebuild/src/server.jsx