解决 Next.js 引入外部 JS 库的问题

阅读时长 7 分钟读完

在 Next.js 中,我们经常会需要引入外部的 JavaScript 库,比如 jQuery、React、Ant Design 或是自己开发的组件库。但是,由于 Next.js 的服务器渲染和客户端渲染的特殊性,引入外部 JS 库可能会遇到一些问题。本文将介绍如何解决 Next.js 引入外部 JS 库遇到的问题,以及如何优化性能。

在客户端引入外部 JS 库

在客户端引入外部 JS 库是比较简单的,只需要像普通网页一样,在 HTML 文件或 JSX 文件中通过 script 标签引入即可。比如:

或是在 JSX 文件中使用 next/head 包装起来,比如:

-- -------------------- ---- -------
------ ---- ---- ------------

-------- ------ -
  ------ -
    --
      ------
        ------- -----------------------------------------------------------
      -------
      ----------- ------------
    ---
  --
-

------ ------- -----

需要注意的是,如果引入的 JS 库依赖于全局变量,比如 jQuery 依赖于 $ 变量,那么需要在组件中使用 window 对象绑定全局变量,具体做法为:

-- -------------------- ---- -------
------ ---- ---- ------------

-------- ------ -
  ------------ -- -
    -------- - ------------- - ------------------
  -- ----

  ------ -
    --
      ------
        ------- -----------------------------------------------------------
      -------
      ----------- ------------
    ---
  --
-

------ ------- -----

这样,jQuery 在客户端就可以正常使用了。

在服务器端引入外部 JS 库

在服务器端渲染时,我们不能直接在 HTML 文件中引入 JS 库,因为这样会使得服务器端和客户端渲染的 HTML 不一致,导致部分功能出现问题。

解决的方法是,在服务器端使用 next/head 包装起来,通过 next/script 组件在客户端引入。比如:

-- -------------------- ---- -------
------ ---- ---- ------------
------ ------ ---- --------------

-------- ------ -
  ------ -
    --
      ------
        -------------- ---------------
      -------
      ------- -----------------------------------------------------------
      ----------- ------------
    ---
  --
-

------ ------- -----

需要注意的是,由于 next/script 组件是在 Head 标签内部,所以在使用 window 对象绑定全局变量时,需要等待客户端加载完成后再绑定,具体做法为:

-- -------------------- ---- -------
------ ---- ---- ------------
------ ------ ---- --------------

-------- ------ -
  ------------ -- -
    ----- ---------- - -- -- -
      -------- - ------------- - ------------------
    --

    -- --------- --- ---------- -
      ------------------------------- ------------
    - ---- -
      -------------
    -

    ------ -- -- ---------------------------------- ------------
  -- ----

  ------ -
    --
      ------
        -------------- ---------------
      -------
      ------- -----------------------------------------------------------
      ----------- ------------
    ---
  --
-

------ ------- -----

这样,在客户端加载完成后,jQuery 就可以正常使用了。

优化性能

当引入的 JS 库比较大时,会影响页面加载速度。为了优化性能,可以使用动态引入的方式,在需要使用的组件中再引入 JS 库。

比如,我们可以创建一个自定义的 next/head 组件,暴露一个 addScript 方法,用于动态引入 JS 库。代码如下:

-- -------------------- ---- -------
------ ---- ---- ------------

----- ------------ - --- ------

-------- ---------------------- -
  ----- - -------- - - ------

  ----- --------- - ----- -- -
    -- ----------------------- -
      -------
    -

    --------------------- ------

    ----- ------ - ---------------------------------
    ---------- - ----
    ------------ - -----
    ------------ - -----

    ----------------------------------
  --

  ----- ------------ - ------- -- -
    -- ----------- --- --------- -
      ----- - --- - - ------------

      -- ----- -
        ---------------
      -
    -

    -- ------------ -- --------------------- -
      ------ -
        ---------
        ------ -
          ---------------
          --------- ---------------------------------------- --------------
        --
      --
    -

    ------ ------
  --

  ------ ----- ---------------------------------------- ----------------------
-

------ ------- ----------------

然后,在需要使用的组件中,使用这个自定义的 Head 组件,动态引入 JS 库。比如:

-- -------------------- ---- -------
------ --------------- ---- --------------------------------

-------- ------ -
  ------ -
    --
      -----------------
        -------------- ---------------
        ------- -----------------------------------------------------------
      ------------------
      ----------- ------------
      ---------------------- - ------------- ---------- --------------
    ---
  --
-

------ ------- -----

这样,在需要使用 jQuery 的组件中再引入,可以避免在整个应用中都引入,优化性能。同时,使用自定义的 Head 组件,也可以避免在每个组件中都写 window 绑定的逻辑,提高代码复用性。

总结

在 Next.js 中引入外部 JS 库需要注意服务器端和客户端渲染的差异,以及对性能的影响。通过本文介绍的方法,可以解决这些问题,并且优化性能,提高代码复用性。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/65a260ddadd4f0e0ffa84a7c

纠错
反馈