有没有办法将 Materialise CDN 与 Next.js 一起使用?
Is there a way to use Materialize CDN with Next.js?
我正在构建一个 Next.js 应用程序,并希望将 Materialise CDN 与它一起使用。在 React 中,我只需在 public/index.html
文件中添加 CDN 链接就可以了。 Next 似乎没有那个,我一直在研究如何做到这一点。
我试过
npm install materialize-css@next --save
然后我将其导入 pages/_app.tsx
,如下所示:
import 'materialize-css/dist/css/materialize.min.css';
import 'materialize-css'
单独导入第一个时效果很好,但是导入第二个添加JS时,报错:
Server Error
ReferenceError: window is not defined
This error happened while generating the page. Any console logs will be displayed in the terminal window.
此外,对于这种导入,我无法对 CSS 进行任何自定义,这就是我想使用 CDN 的原因。我已经做了好几天了,运气不好。
与其在 _app.tsx
中执行,不如在 _document.js
文件中执行。这个文件是你在 NextJS 项目中增加 html 和 body 标签的地方。重要的是要注意它必须是 .js 文件,而不是 .tsx.
默认情况下,此文件不存在于您的项目中,它是由 nextJS 自动生成的,但您可以在 pages 文件夹中创建它以覆盖默认文件并在那里导入 CDN。
您有 _document.js 模板和 the official documentation 中的更多信息。
通过 CDN 使用 Materialise
作为 ,您可以在自定义 _document
中添加 CDN 链接,这样 CSS 和 JavaScript 都可以在浏览器中正确加载。
// /pages/_document.js
class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
/>
</Head>
<body>
<Main />
<NextScript />
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</body>
</Html>
);
}
}
因为 Materialize 在内部使用 Web API,所以您需要在 useEffect
中访问附加到 window
的 Materialise 实例。当页面由 Next.js.
在服务器上预呈现时,这可以防止 ReferenceError: window is not defined
错误
下面是一个小示例,说明如何在呈现轮播的组件中使用 Materialize。
const MaterializeCarousel = () => {
useEffect(() => {
const elems = document.querySelectorAll('.carousel');
const instances = window.M.Carousel.init(elems);
}, []);
return (
<div className="carousel">
<a className="carousel-item" href="#one!"><img src="https://lorempixel.com/250/250/nature/1" /></a>
<a className="carousel-item" href="#two!"><img src="https://lorempixel.com/250/250/nature/2" /></a>
<a className="carousel-item" href="#three!"><img src="https://lorempixel.com/250/250/nature/3" /></a>
<a className="carousel-item" href="#four!"><img src="https://lorempixel.com/250/250/nature/4" /></a>
<a className="carousel-item" href="#five!"><img src="https://lorempixel.com/250/250/nature/5" /></a>
</div>
);
};
通过 npm 包使用 Materialise
另一种选择是通过其 npm 包使用库 materialize-css
。
您首先需要像在 _app
中一样导入全局 CSS。
import 'materialize-css/dist/css/materialize.min.css';
无法在此处加载 JavaScript 代码,如前所述,它使用无法在服务器上运行的 Web API。
相反,以相同的轮播组件为例,您应该在 useEffect
中动态导入 materialize-css
,这样它只在客户端加载。
const MaterializeCarousel = () => {
useEffect(() => {
const init = async () => {
const M = await import('materialize-css');
const elems = document.querySelectorAll('.carousel');
const instances = M.Carousel.init(elems);
};
init();
}, []);
return (
<div className="carousel">
<a className="carousel-item" href="#one!"><img src="https://lorempixel.com/250/250/nature/1" /></a>
<a className="carousel-item" href="#two!"><img src="https://lorempixel.com/250/250/nature/2" /></a>
<a className="carousel-item" href="#three!"><img src="https://lorempixel.com/250/250/nature/3" /></a>
<a className="carousel-item" href="#four!"><img src="https://lorempixel.com/250/250/nature/4" /></a>
<a className="carousel-item" href="#five!"><img src="https://lorempixel.com/250/250/nature/5" /></a>
</div>
);
};
我正在构建一个 Next.js 应用程序,并希望将 Materialise CDN 与它一起使用。在 React 中,我只需在 public/index.html
文件中添加 CDN 链接就可以了。 Next 似乎没有那个,我一直在研究如何做到这一点。
我试过
npm install materialize-css@next --save
然后我将其导入 pages/_app.tsx
,如下所示:
import 'materialize-css/dist/css/materialize.min.css';
import 'materialize-css'
单独导入第一个时效果很好,但是导入第二个添加JS时,报错:
Server Error
ReferenceError: window is not defined
This error happened while generating the page. Any console logs will be displayed in the terminal window.
此外,对于这种导入,我无法对 CSS 进行任何自定义,这就是我想使用 CDN 的原因。我已经做了好几天了,运气不好。
与其在 _app.tsx
中执行,不如在 _document.js
文件中执行。这个文件是你在 NextJS 项目中增加 html 和 body 标签的地方。重要的是要注意它必须是 .js 文件,而不是 .tsx.
默认情况下,此文件不存在于您的项目中,它是由 nextJS 自动生成的,但您可以在 pages 文件夹中创建它以覆盖默认文件并在那里导入 CDN。
您有 _document.js 模板和 the official documentation 中的更多信息。
通过 CDN 使用 Materialise
作为 _document
中添加 CDN 链接,这样 CSS 和 JavaScript 都可以在浏览器中正确加载。
// /pages/_document.js
class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
/>
</Head>
<body>
<Main />
<NextScript />
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</body>
</Html>
);
}
}
因为 Materialize 在内部使用 Web API,所以您需要在 useEffect
中访问附加到 window
的 Materialise 实例。当页面由 Next.js.
ReferenceError: window is not defined
错误
下面是一个小示例,说明如何在呈现轮播的组件中使用 Materialize。
const MaterializeCarousel = () => {
useEffect(() => {
const elems = document.querySelectorAll('.carousel');
const instances = window.M.Carousel.init(elems);
}, []);
return (
<div className="carousel">
<a className="carousel-item" href="#one!"><img src="https://lorempixel.com/250/250/nature/1" /></a>
<a className="carousel-item" href="#two!"><img src="https://lorempixel.com/250/250/nature/2" /></a>
<a className="carousel-item" href="#three!"><img src="https://lorempixel.com/250/250/nature/3" /></a>
<a className="carousel-item" href="#four!"><img src="https://lorempixel.com/250/250/nature/4" /></a>
<a className="carousel-item" href="#five!"><img src="https://lorempixel.com/250/250/nature/5" /></a>
</div>
);
};
通过 npm 包使用 Materialise
另一种选择是通过其 npm 包使用库 materialize-css
。
您首先需要像在 _app
中一样导入全局 CSS。
import 'materialize-css/dist/css/materialize.min.css';
无法在此处加载 JavaScript 代码,如前所述,它使用无法在服务器上运行的 Web API。
相反,以相同的轮播组件为例,您应该在 useEffect
中动态导入 materialize-css
,这样它只在客户端加载。
const MaterializeCarousel = () => {
useEffect(() => {
const init = async () => {
const M = await import('materialize-css');
const elems = document.querySelectorAll('.carousel');
const instances = M.Carousel.init(elems);
};
init();
}, []);
return (
<div className="carousel">
<a className="carousel-item" href="#one!"><img src="https://lorempixel.com/250/250/nature/1" /></a>
<a className="carousel-item" href="#two!"><img src="https://lorempixel.com/250/250/nature/2" /></a>
<a className="carousel-item" href="#three!"><img src="https://lorempixel.com/250/250/nature/3" /></a>
<a className="carousel-item" href="#four!"><img src="https://lorempixel.com/250/250/nature/4" /></a>
<a className="carousel-item" href="#five!"><img src="https://lorempixel.com/250/250/nature/5" /></a>
</div>
);
};