Razzle: Verwendung mit nicht transpiliertem Modul in node_modules?

Erstellt am 1. Juli 2018  ·  6Kommentare  ·  Quelle: jaredpalmer/razzle

Hallo!

Ich versuche, eine Bibliothek zu verwenden, die nicht transpiliert an NPM geliefert wird und daher lokal im Razzle-Projekt transpiliert werden muss. Ich habe meine razzle-config geändert, um das Modul für die Transpilation in den js-Loader aufzunehmen, und das scheint für den Client-Build gut zu funktionieren, da es keine Fehler mehr gibt. Ich erhalte jedoch den Fehler "unerwarteter Token-Import" in dem, was ich für den Server-Build halte.

Irgendwelche Ideen dazu? Ich denke, das Problem ist, dass das Modul irgendwie auch für den Server transpiliert werden muss?

Vielen Dank im Voraus!

Hilfreichster Kommentar

Okay, ich habe es herausgefunden. Sie müssen die Includes von babel-loader erweitern. Außerdem müssen Sie babelOptions explizit festlegen, es sei denn, sie sind in einem .babelrc innerhalb des nicht transpilierten Pakets angegeben. Es reicht nicht aus, ein /babelrc in Ihrem Apps-Paket zu haben.

Hier ist eine vollständige Beispielkonfiguration:

'use strict';
const nodeExternals = require('webpack-node-externals');
const fs = require('fs');

module.exports = {
  modifyBabelOptions() {
    return {
      presets: ['razzle/babel'],
      plugins: ['transform-flow-strip-types'],
    };
  },
  modify(config, { target, dev }, webpack) {
    // package un-transpiled packages
    const babelRuleIndex = config.module.rules.findIndex(
      (rule) => rule.use && rule.use[0].loader && rule.use[0].loader.includes('babel-loader')
    );
    config.module.rules[babelRuleIndex] = Object.assign(config.module.rules[babelRuleIndex], {
      include: [
        ...config.module.rules[babelRuleIndex].include,
        fs.realpathSync('./node_modules/untranspiled-package')
      ],
    });
    config.externals =
      target === 'node'
        ? [
            nodeExternals({
              whitelist: [
                dev ? 'webpack/hot/poll?300' : null,
                /\.(eot|woff|woff2|ttf|otf)$/,
                /\.(svg|png|jpg|jpeg|gif|ico)$/,
                /\.(mp4|mp3|ogg|swf|webp)$/,
                /\.(css|scss|sass|sss|less)$/,
                /^untranspiled-package/,
              ].filter(Boolean),
            }),
          ]
        : [];
    // return
    return config;
  },
};

Alle 6 Kommentare

Konnte es lösen. Als zukünftige Referenz:

Es stellt sich heraus, dass webpack-node-externals während SSR angewendet und verwendet wird, was bedeutet, dass keine Module von node_modules zum Bündeln und damit zum Transpilieren enthalten sind. Ich habe es gelöst, indem ich etwas in dieser Richtung in meinem razzle.config.js gemacht habe:

config.externals = target === 'node' ? [
      nodeExternals({
        whitelist: [
          dev ? 'webpack/hot/poll?300' : null,
          /\.(eot|woff|woff2|ttf|otf)$/,
          /\.(svg|png|jpg|jpeg|gif|ico)$/,
          /\.(mp4|mp3|ogg|swf|webp)$/,
          /\.(css|scss|sass|sss|less)$/,
          /^my-untranspiled-package/
        ].filter(Boolean),
      }),
    ] : [];

...wo ein Großteil dieses Codes direkt von createConfig.js in dieses Repo kopiert wird.

@zth danke!!

@zth wie hast du es überhaupt auf der Clientseite zum Laufen gebracht? könntest du deine config teilen?

Okay, ich habe es herausgefunden. Sie müssen die Includes von babel-loader erweitern. Außerdem müssen Sie babelOptions explizit festlegen, es sei denn, sie sind in einem .babelrc innerhalb des nicht transpilierten Pakets angegeben. Es reicht nicht aus, ein /babelrc in Ihrem Apps-Paket zu haben.

Hier ist eine vollständige Beispielkonfiguration:

'use strict';
const nodeExternals = require('webpack-node-externals');
const fs = require('fs');

module.exports = {
  modifyBabelOptions() {
    return {
      presets: ['razzle/babel'],
      plugins: ['transform-flow-strip-types'],
    };
  },
  modify(config, { target, dev }, webpack) {
    // package un-transpiled packages
    const babelRuleIndex = config.module.rules.findIndex(
      (rule) => rule.use && rule.use[0].loader && rule.use[0].loader.includes('babel-loader')
    );
    config.module.rules[babelRuleIndex] = Object.assign(config.module.rules[babelRuleIndex], {
      include: [
        ...config.module.rules[babelRuleIndex].include,
        fs.realpathSync('./node_modules/untranspiled-package')
      ],
    });
    config.externals =
      target === 'node'
        ? [
            nodeExternals({
              whitelist: [
                dev ? 'webpack/hot/poll?300' : null,
                /\.(eot|woff|woff2|ttf|otf)$/,
                /\.(svg|png|jpg|jpeg|gif|ico)$/,
                /\.(mp4|mp3|ogg|swf|webp)$/,
                /\.(css|scss|sass|sss|less)$/,
                /^untranspiled-package/,
              ].filter(Boolean),
            }),
          ]
        : [];
    // return
    return config;
  },
};

Ich habe es geschafft, den gleichen Trick wie @MrLoh auch für Typescript ts-loader zu machen. Kreuzen Sie AllowedPackages an, dort können Sie Ihren Paketnamen einfügen. Ich habe auch eine Idee berücksichtigt, dass es für die aktuelle Version von Razzle anscheinend ausreicht, ohne benutzerdefinierte config.externals zu sein, aber Sie könnten auch an der ursprünglichen @MrLoh- Lösung interessiert sein (siehe zum Löschen von config.externals: https:// github.com/jaredpalmer/razzle/issues/842#issuecomment-475722036)

  const allowedPackages = ['my-component']

  const allowedPackagePaths = allowedPackages.map(packageName =>
    fs.realpathSync('./node_modules/' + packageName)
  )

  const tsRuleIndex = config.module.rules.findIndex(
    rule =>
      rule.use && rule.use[0].loader && rule.use[0].loader.includes('ts-loader')
  )

  if (tsRuleIndex === -1) {
    throw Error(
      'This component assumes that you are using ts-loader. If you are not using it, then you might need to check and test code for how would it work with other loaders'
    )
  }

  config.module.rules[tsRuleIndex] = {
    ...config.module.rules[tsRuleIndex],

    include: [
      ...config.module.rules[tsRuleIndex].include,
      ...allowedPackagePaths,
    ],
  }

  delete config.externals

Das hat bei mir funktioniert. Meine Frage lautet: Die Bibliotheken werden im Client- und Server-Bundle dupliziert. Gibt es eine Möglichkeit, dies gemeinsam mit razzle.config.js in eine neue Datei zu zerlegen?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

Jayphen picture Jayphen  ·  4Kommentare

krazyjakee picture krazyjakee  ·  3Kommentare

GouthamKD picture GouthamKD  ·  3Kommentare

sebmor picture sebmor  ·  4Kommentare

ewolfe picture ewolfe  ·  4Kommentare