How to add externals like in webpack in Next.js 13?

348 Views Asked by At

In webpack as I found you can add "externals" to load additional component like modules into applications and import them.As you can see "ymaps3" is used to load external script which has no react wrapper. It is has following webpack demo code:

// Generated using webpack-cli https://github.com/webpack/webpack-cli
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const isProduction = process.env.NODE_ENV == "production";

const config = {
  entry: "./src/index.ts",
  output: {
    path: path.resolve(__dirname, "dist")
  },
  devServer: {
    host: "localhost"
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "index.html"
    })
  ],
  externalsType: "script",
  externals: {
    // ymaps3: ["https://api-maps.yandex.ru/3.0/?apikey=4a75efd1-e36a-4f02-8957-954d09371435&lang=ru-RU", "ymaps3"],
    ymaps3: [
      `promise new Promise((resolve) => {
        const script = document.createElement('script');
        script.src = "https://api-maps.yandex.ru/3.0/?apikey=4a75efd1-e36a-4f02-8957-954d09371435&lang=ru-RU";
        script.async = true;
        script.onload = () => {
          ymaps3.ready.then(() => resolve(ymaps3));
          script.remove();
        };
        document.body.appendChild(script);
      })`
    ]
  },
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/i,
        loader: "ts-loader",
        exclude: ["/node_modules/"]
      }
    ]
  },
  resolve: {
    extensions: [".tsx", ".ts", ".jsx", ".js", "..."]
  }
};

module.exports = () => {
  if (isProduction) {
    config.mode = "production";
  } else {
    config.mode = "development";
  }
  return config;
};

What I'm trying to do is to import 'ymaps3' as module and use it as follows:

import * as ymaps3 from 'ymaps3';
import React, {useState, useEffect} from 'react';

// ...

function Map() {
  const [loaded, setLoaded] = useState(true);

  useEffect(() => {
    ymaps3.ready.then(() => setLoaded(false));
  }, []);

  if (loaded) {
    return <div>Loading...</div>;
  }

  const reactify = ymaps3.reactify.bindTo(React, ReactDOM);
  const {YMap} = reactify.module(ymaps3);

  return <YMap />;
}

function App() {
  return (
    <div>
      <button>Button</button>
      <Map />
    </div>
  );
}```
1

There are 1 best solutions below

0
Fedechka On

You can import components from yamap3 without externals in webpack by adding this library:

import React from "react";
import {
  YMap,
  YMapDefaultSchemeLayer,
  YMapDefaultFeaturesLayer
  // ...other components
} from "ymapv3-components";
import { features, LOCATION } from './helpers'

function Map() {
  return (
    <YMapComponentsProvider apiKey={process.env.REACT_APP_YMAP_KEY}>
      <YMap location={location}>
        <YMapDefaultSchemeLayer />
        <YMapDefaultFeaturesLayer />
        <YMapDefaultMarker
          coordinates={LOCATION.coordinates}
        />
      </YMap>
    </YMapComponentsProvider>
  );
}

export default Map;

check an example in codesandbox