چانک کردن Sass فایل‌ها در Next.js

در پروژه جدید خودم و سعید تصمیم گرفتیم که از فریم‌ورک ری‌اکت Next.js استفاده کنیم، مهمترین قابلیت این فریم‌ورک کانفیگ SSR اشه ولی خب به همین راحتی هم نمیتونین از یه پروژه‌ای که با CRA استارت زدین به Next.js مهاجرت کنین به این خاطر من و سعید توی این جابه‌جایی چالش‌های زیادی داشتیم، که البته سعی داریم این تجربه رو کم کم در ویرگول با شما به اشتراک بگذاریم.

چانک (Chunk) یکی از شاخه‌های وب‌پک به نام Code Splitting محسوب میشه و خیلی ساده بخوام تعریفش رو بگم شکستن و تکه تکه کردن فایل‌های تولید شده برای هر کامپوننت اِ که دیگه شما یک فایل 2، 3 مگی واسه کل پروژتون ندارید و اون‌ها رو به فایل‌های چند کیلوبایتی میشکونید.

خب هدف من از نوشتن این مقاله معرفی و توسعه‌ی یکی از پلاگین‌های Next.js به نام zeit/next-sass که یکسری محدودیت‌ها از جمله استفاده‌ی همزمان از sass module و sass غیر ماژولی و مهمتر از اون چانک کردن فایل‌های sass ایه که در نهایت من این پلاگین رو کوبیدم و از نو ساختم.

برای شروع پکیج مورد نظر رو نصب کنید.

npm install --save @2012mjm/next-sass

یا از روش زیر، که من خودم yarn رو بیشتر دوس دارم.

yarn add @2012mjm/next-sass

در فایل next.config.js پروژه Next.js یتون پلاگین مورد نظر رو import و به روشی که نوشتم اون رو به فریم‌ورکتون متصل کنید.

const withSass = require('@2012mjm/next-sass')

module.exports = withSass({
    /* config options here */
})

حالا کنار کامپوننت موردنظرتون یک فایل برای مثال با نام styles.module.scss ایجاد کنید، و چند خط sass ای توی اون تایپ کنید.

$font-size: 50px;
.example {
    font-size: $font-size;
}

و بعد به شکل زیر در کامپوننتون import اش کنین

import styles from "../styles.module.scss"
export default () => <div className={styles.example}>Hello World!</div>

به همین راحتی ...

البته تا این جای کار رو خود پلاگین zeit/next-sass واستون انجام میده، اولین مشکلی که ما بهش برخوردیم، استفاده از sass بوت‌استرپ بود که وقتی پلاگین رو روی ماژول بیس تنظیم می‌کردیم تمام sass فایل‌های ماژولی بیلد و تمامی سلکتورهای css بوت‌استرپ داغون میشدن، برای حل این مشکل فایل‌هایی که با پسوند module.scss یا module.sass باشن رو ماژولی کامپایل و فایل هایی که تنها پسوند scss یا sass داشته باشن رو غیر ماژولی کامپایل کردیم.

مشکل دوم که به عنوان تاپیک این مقاله انتخاب کردم این بود که فایل sass تمامی کامپوننت‌ها در قالب یک فایل کامپایل میشد و حجم فایل استایل پروژه خیلی خیلی بالا میرفت، مخصوصا در پروژه‌هایی که scale بالا داشتن، برای حل این مشکل مجبور شدم یه خرده با webpack دست و پنجه نرم کنم که در نهایت موفق شدم با استفاده از پلاگین وب‌پک extract-css-chunks-webpack-plugin این مشکل رو هم رفع کنم.

فقط نکته‌ی مهمی که وجود داره اینکه باید صفحات رو به صورت dynamic ایمپورت کنید تا فایل css هر page با لود شدن همزمان اون فراخوانی بشه، به این صورت:

// pages/index.js

import dynamic from 'next/dynamic';
const Home = dynamic(() =>
    import(/* webpackChunkName: "home.js" */ '../src/scenes/Home/Home')
);
export default Home;

اون /* webpackChunkName: "home.js" */ واسه جاوااسکریپت کامنت محسوب میشه ولی واسه وب‌پک یه رشته‌ی معنی داره و اگه اونو ننویسین باعث میشه به یک خطای مرگبار در هنگام بیلد پروداکشن بخورین، دلیلشم اینکه وب‌پک به جای home.js اسم چانک‌ها رو یک و دو و سه میزاره.

نکته آخر هم اینکه اگه خواستین پلاگین مورد نظر رو به صورت سفارشی کانفیگ کنید، به روشی که من واسه پروژمون کانفیگ کردم می‌تونین انجامش بدین.

module.exports = withSass({
  cssLoaderOptions: {
    importLoaders: 1,
    localIdentName: '[local]_[hash:base64:5]'
  },
  cssExtractOutput: {
    filename: {
      dev: 'static/css/[name].css',
      prod: 'static/css/[contenthash:8].css'
    },
    chunkFilename: {
      dev: 'static/css/[name].chunk.css',
      prod: 'static/css/[contenthash:16].css'
    }
  })
)

مستندات کامل این پکیج هم در آدرس زیر قابل دسترسه

https://www.npmjs.com/package/@2012mjm/next-sass