algolia / instantsearch

⚡️ Libraries for building performant and instant search and recommend experiences with Algolia. Compatible with JavaScript, TypeScript, React and Vue.
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/
MIT License
3.74k stars 527 forks source link

Error in bundling InstantSearch with Svelte/Rollup #5072

Closed thedivtagguy closed 2 years ago

thedivtagguy commented 2 years ago

I am trying to get Algolia InstantSearch.js working with my Svelte website. I get the following error when I try to deploy this on Netlify, I get the following error:

9:27:35 PM: [vite]: Rollup failed to resolve import "instantsearch.js/es/widgets.js" from "src/components/Search/SearchSection.svelte".
9:27:35 PM: This is most likely unintended because it can break your application at runtime.
9:27:35 PM: If you do want to externalize this module explicitly add it to
9:27:35 PM: `build.rollupOptions.external`
9:27:35 PM: > [vite]: Rollup failed to resolve import "instantsearch.js/es/widgets.js" from "src/components/Search/SearchSection.svelte".
9:27:35 PM: This is most likely unintended because it can break your application at runtime.
9:27:35 PM: If you do want to externalize this module explicitly add it to
9:27:35 PM: `build.rollupOptions.external`

This is how I import those modules in my component:

import algoliasearch from 'algoliasearch/lite.js';
import instantsearch from 'instantsearch.js';
import { searchBox, hits, index } from 'instantsearch.js/es/widgets.js';

This is my svelte.config.js:

import fs from "fs";
import path from "path";
import adapterStatic from "@sveltejs/adapter-static";
import svg from "vite-plugin-svgstring";
import dsv from "@rollup/plugin-dsv";
import sveltePreprocess from "svelte-preprocess";
import autoprefixer from "autoprefixer";
import { indexAlgolia } from 'svelte-algolia/server-side'
import 'dotenv/config' // optional

const { thedivtagguy } = JSON.parse(fs.readFileSync("package.json", "utf8"));
const dev = process.env.NODE_ENV === "development";
const dir = thedivtagguy ? thedivtagguy.subdirectory : "";
const prefix = dir.startsWith("/") ? "" : "/";
const base = dev || !dir ? "" : `${prefix}${dir}`;

const preprocess = sveltePreprocess({
  postcss: {
    plugins: [autoprefixer]
  }
});

const config = {
  preprocess,
  kit: {
    adapter: adapterStatic(),
    target: "#svelte",
    vite: {
      resolve: {
        alias: {
          $actions: path.resolve("./src/actions"),
          $components: path.resolve("./src/components"),
          $data: path.resolve("./src/data"),
          $stores: path.resolve("./src/stores"),
          $styles: path.resolve("./src/styles"),
          $svg: path.resolve("./src/svg"),
          $utils: path.resolve("./src/utils")
        }
      },
      plugins: [dsv(), svg()],
    },
    paths: {
      base
    }
  }
};

export default config;

This is rollup.config.js:

import sveltePreprocess from "svelte-preprocess";
import svelte from "rollup-plugin-svelte";
import geojson from 'rollup-plugin-geojson';
import { mdsvex } from "mdsvex";
const production = !process.env.ROLLUP_WATCH;

preprocess: sveltePreprocess({
  sourceMap: !production,
  postcss: {
    plugins: [require("tailwindcss"), require("autoprefixer")]
  }
});

export default {
  plugins: [
    svelte({
            // tell svelte to handle mdsvex files
            extensions: [".svelte", ".svx"],
            preprocess: mdsvex()
        }),
    geojson()
  ],
};

How and where exactly do I "externalize this module explicitly"? I can't find any good documentation for this.

francoischalifour commented 2 years ago

The import should either be:

I don't think we document instantsearch.js/es/widgets.js anywhere, as it doesn't exist.

Can you try one of these?

thedivtagguy commented 2 years ago

@francoischalifour I tried that and it occasionally loads now. However, if I try to build it on Netlify, here is what I get:

1:22:02 PM: > Using @sveltejs/adapter-static
1:22:02 PM: (node:1477) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
1:22:02 PM: > Unexpected token 'export'
1:22:02 PM: /opt/build/repo/node_modules/instantsearch.js/es/widgets/index.js:1
1:22:02 PM: export { default as clearRefinements } from './clear-refinements/clear-refinements';
1:22:02 PM: ^^^^^^
1:22:02 PM: SyntaxError: Unexpected token 'export'
1:22:02 PM:     at Object.compileFunction (node:vm:352:18)
1:22:02 PM:     at wrapSafe (node:internal/modules/cjs/loader:1033:15)
1:22:02 PM:     at Module._compile (node:internal/modules/cjs/loader:1069:27)
1:22:02 PM:     at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
1:22:02 PM:     at Module.load (node:internal/modules/cjs/loader:981:32)
1:22:02 PM:     at Function.Module._load (node:internal/modules/cjs/loader:822:12)
1:22:02 PM:     at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
1:22:02 PM:     at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
1:22:02 PM:     at async Promise.all (index 0)
1:22:02 PM:     at async ESMLoader.import (node:internal/modules/esm/loader:385:24)

This is my package.json:

{
  "name": "svelte-starter",
  "version": "3.0.0",
  "scripts": {
    "dev:only": "svelte-kit dev",
    "build:only": "svelte-kit build",
    "preview": "svelte-kit preview",
    "tailwind:watch": "cross-env TAILWIND_MODE=watch cross-env NODE_ENV=development  postcss src/styles/tailwind.css -o static/app.css -w",
    "tailwind:build": "cross-env TAILWIND_MODE=build cross-env NODE_ENV=production  postcss src/styles/tailwind.css -o static/app.css",
    "dev": "concurrently \"npm run dev:only\" \"npm run tailwind:watch\" ",
    "build": "npm run gdoc && npm run json && npm run tailwind:build && npm run build:only cross-env NODE_ENV=production",
    "style": "node tasks/style-dictionary.cjs",
    "start": "svelte-kit start",
    "lint": "prettier --check .",
    "format": "prettier --write ."
  },
  "devDependencies": {
    "@rollup/plugin-dsv": "2.0.2",
    "@rollup/plugin-replace": "^4.0.0",
    "@sveltejs/adapter-netlify": "^1.0.0-next.51",
    "@sveltejs/adapter-static": "1.0.0-next.21",
    "@sveltejs/kit": "1.0.0-next.190",
    "@types/d3": "^7.1.0",
    "archieml": "^0.5.0",
    "autoprefixer": "^10.4.0",
    "d3": "^7.4.4",
    "dotenv": "^16.0.1",
    "feather-icons": "4.28.0",
    "google-drive-getfilelist": "^1.0.5",
    "lodash.debounce": "4.0.8",
    "mapbox-gl": "^2.8.2",
    "node-fetch": "^2.6.7",
    "postcss": "^8.4.5",
    "postcss-import": "^14.0.2",
    "prettier": "2.4.1",
    "prettier-plugin-svelte": "2.4.0",
    "rollup-plugin-geojson": "^0.1.0",
    "rollup-plugin-postcss": "^4.0.2",
    "rollup-plugin-svg": "2.0.0",
    "style-dictionary": "3.0.3",
    "svelte": "3.44.0",
    "svelte-algolia": "^0.2.15",
    "svelte-preprocess": "4.9.8",
    "tailwindcss": "^3.0.7",
    "vite-plugin-svgstring": "1.0.0"
  },
  "type": "module",
  "engines": {
    "node": ">= 16.0.0"
  },
  "browserslist": "> 0.5%, last 4 versions, not ie <= 11, not ie_mob <= 11",
  "thedivtagguy": {
    "subdirectory": ""
  },
  "dependencies": {
    "@sveltejs/pancake": "^0.0.18",
    "algoliasearch": "^4.13.1",
    "csv": "^6.1.0",
    "csv2geojson": "^5.1.1",
    "instantsearch.js": "^4.7.0"
  }
}

As you can see, type is already set to module. What can I do now?

Haroenv commented 2 years ago

Do you have this in a consistent reproduction somewhere @thedivtagguy? An other option you can also try is the individual file you're trying to import, so for example instantsearch.js/es/widgets/clear-refinements/index.js, but without direct reproduction, help will be hard

I however note that you depend on InstantSearch.js 4.7.0, the { type: module } was only added in later versions, so if you could update, maybe that is also possibly the cause (maybe netlify installs a different, older, version than you locally)

Haroenv commented 2 years ago

There was no reproduction, so I assume this is fixed. If you have a similar issue, please create a new ticket and attach a reproduction, thanks!