Next.js: استيراد ملفات CSS؟

تم إنشاؤها على ٢٧ ديسمبر ٢٠١٦  ·  102تعليقات  ·  مصدر: vercel/next.js

أحيانًا يكون من الجيد تقسيم CSS إلى ملف .css منفصل. لقد حاولت القيام بما يلي:

pages/
└── index
    ├── index.css
    ├── index.js
    └── component.js

ثم في index.js ، حاولت القيام بما يلي:

import css from './index.css'

وفي next.config.js:

module.exports = {
  webpack: function (config) {
    config.module.loaders = (config.module.loaders || []).concat({
      test: /\.css$/, loader: 'raw'
    })
    return config
  }
}

لكن لسوء الحظ ، يستمر في إعطائي:

 ERROR  Failed to compile with 1 errors

This dependency was not found in node_modules:

* ./index.css

يبدو أنه لم يتم الانتقال إلى المكان الصحيح لسبب ما ، فإن component.js المحلي يعمل عبر import component from './component.js' ، لذلك لست متأكدًا مما يحدث هنا.

التعليق الأكثر فائدة

إليك حل بسيط لاستيراد ملفات CSS باستخدام babel-plugin-inline-import :

.babelrc

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "inline-import",
      {
        "extensions": [".css"]
      }
    ]
  ]
}

الصفحة / المكون

import "prismjs";

import { PrismCode } from "react-prism";
import prismGlobalStyles from "prismjs/themes/prism.css";

export default () => {
    return (
        <div>
            <style global jsx>
                {prismGlobalStyles}
            </style>
            <PrismCode className="language-javascript">
                {`function(noop) {
                    return noop;
                }`}
            </PrismCode>
            {/* ... */}
        </div>
    );
};

ال 102 كومينتر

تقصد هذا لا يعمل على الخادم؟
أعتقد أنه ليس لدينا حل بديل لهذا بعد. سي سيarunoda

حسنًا ، أعتقد أنه يجب أن تكون هناك طريقة لتهيئة حزمة الويب في next.config.js للعمل على كلا الجانبين حتى يعمل هذا.

لدي مشكلة مماثلة في الملعب حيث لا يمكنني الحصول على Next للعب بشكل جيد مع CSS أو SASS. لديّ دليل components يحتوي على مكونات React القياسية حيث أقوم باستيرادها إلى صفحاتي ولكن كلما حاولت الاستيراد في ملفات SASS (أو CSS) ، أحصل على ~ "تحتاج إلى استخدام أداة التحميل المناسبة لهذا الملف" اكتب رسالة خطأ.

بشكل عام في React ، أستورد ملفات SASS ولدي Webpack compile باستخدام محمل style و css و sass. لقد حاولت إضافة هذه إلى ملف next.config.js (وقام NPM بتثبيتها) ولكن ما زلت أتلقى نفس رسالة الخطأ.

ملفي next.config.js :

module.exports = {
  webpack: (config, { dev }) => {
    config.module.rules.push({ test: /\.scss$/, loader: ['style-loader', 'css-loader', 'sass-loader'] });
    return config;
  }
}

عذرًا إذا بدت هذه الأسئلة غبية أو فاتني شيء واضح في المستندات يوضح الإجابات عليها ، ولكن إذا كان لدى أي شخص مثال عملي لاستيراد / تجميع SASS (أو على الأقل CSS) في مكون أو صفحة بها كل ما هو مطلوب لإضافته إلى next.config.js لتحميلها / تجميعها ، سأقدر ذلك بشكل كبير. شكر!

أنا أستخدم css-modules-need-hook
لجعل المغلق يعمل.

spacedragon هل لديك مثال على كيفية دمج css-modules-need-hook مع Next.js؟ أواجه مشاكل في العمل.

ما زلت أواجه مشكلات في الحصول على SASS للتجميع إذا كان بإمكان أي شخص إلقاء بعض الضوء على كيفية القيام بذلك أو مجرد استيراد ملف CSS داخل Next ، فسيكون ذلك موضع تقدير (عبر مثال رمز).

من المثير للاهتمام أنه تم تحديث ملف README لإزالة مثال أداة تحميل SVG وتغييره ليقول إن إضافة برامج تحميل لملف مثل SVG و CSS و SASS غير محبذة. لست متأكدًا من سبب كون CSS المضمَّن على ما يرام ولكن CSS المستوردة ليست كذلك ، لكنني متأكد من وجود سبب وجيه لذلك. أنا غير متأكد حاليًا من أفضل إستراتيجية للتعامل مع CSS و SASS معرّفين / مضمنين لـ JS.

MikeDigitize راجع التعليق على # 627 و # 638.

من الممكن في الواقع وسهولة معالجة الأنماط على جانب الخادم.

مباشرة في العقدة:

require.extensions['.css'] = function(file) {
    console.log(file.id)
    return;
}

عبر سجل بابل:

// from https://babeljs.io/docs/core-packages/babel-register/
require("babel-register")({
  // Optional ignore regex - if any filenames **do** match this regex then they
  // aren't compiled.
  ignore: /regex/,

  // Ignore can also be specified as a function.
  ignore: function(filename) {
    if (filename === '/path/to/es6-file.js') {
      return false;
    } else {
      return true;
    }
  },

  // Optional only regex - if any filenames **don't** match this regex then they
  // aren't compiled
  only: /my_es6_folder/,

  // Setting this will remove the currently hooked extensions of .es6, `.es`, `.jsx`
  // and .js so you'll have to add them back if you want them to be used again.
  extensions: [".es6", ".es", ".jsx", ".js"]
});

عبر لوادر webpack:

أنا شخصياً أستخدم مُحمل نمط متماثل الشكل لأنه يسمح لي بتضمين CSS الحرج أثناء العرض على الخادم. إعادة التحميل الساخنة والأشياء الأخرى ذات الصلة بـ DX تعمل أيضًا. لست معجبًا حقًا بـ CSS في JS لأنه يعقد استخدام مكونات الطرف الثالث ويأخذ بطريقة ما C من CSS.

viktorbezdek هل نجحت في استخدام مُحمل النمط المتماثل مع next.js؟

noeljackson ليس حقًا ، لكني أنوي ذلك. يبدو Next.js واعدًا ويمكن أن يوفر لي الكثير من الوقت إذا نجحت في ذلك. سننظر فيه خلال الأسبوع أو الأسبوعين القادمين ، وأرسل طلب السحب إذا نجحت.

viktorbezdek سأضع مكافأة على هذا ، لأنه حقًا مهم لمشروع أعمل عليه. أعلم أنني لست غير كفؤ ، لكنني لا أفهم كيفية تصحيح تحولات بابل بما يكفي لمعرفة ذلك. لقد حاولت تبديل هذه الأفكار ولا شيء يعمل بنسبة 100٪. لقد تمكنت من الحصول على أداة تحميل خام لسحب ورقة أنماط مشفرة بالبيانات باستخدام برامج babel-plugin-webpack-loaders ، ولكن لا يعمل أي من اللوادر ذات النمط. شكرا على الرنين! :) مقدر جدا.

هل هناك حل لهذا؟ أرغب في رؤية حل لذلك لا يتعين علي تضمين css عالميًا.

FWIW ، لقد قمت للتو بوضع ملفات CSS في المجلد /static . لم يكن مكانًا رائعًا ، ولكن ليس صفقة ضخمة أيضًا.

سيكون هناك حل. أنا فقط لم أتمكن من الانتهاء منه. لدي أول نموذج محلي يبدو أنه يعمل ، إلا أنه يحتاج إلى ساعات قليلة ليتم الانتهاء منه. أنا متأكد من أنني سأنتهي بعد نهاية الأسبوع. ترقب.

matthewmueller أنت تستخدم وحدات CSS؟

viktorbezdek شكرا للعمل على هذا! دعم وحدات CSS (أو ما شابه) مهم لهذا المشروع IMO. jsx المصمم ، مناسب للمواقف البسيطة ولكن يصعب قراءته للمكونات المصممة بشكل كبير.

هل سيكون ملحق بابل مثل هذا خيارًا (جانب الخادم أيضًا)؟ https://github.com/gajus/babel-plugin-react-css-modules

حاولت تشغيل هذا ولكن لم يحالفني الحظ: /

حصلت على وحدات CSS نوع من العمل مع babel-plugin-css-modules-transform . انظر بلدي على سبيل المثال hacky في بلدي تفرع .

الجانب السلبي هو أنه يجب عليك قتل الخادم وإعادة تشغيله في كل مرة تقوم فيها بإجراء تغيير على CSS.

تعرض بعض مكونات React التصميم الافتراضي من خلال مورد ثابت قادر على import . على سبيل المثال لاستيراد النمط الافتراضي لـ https://github.com/react-component/slider ، قد يستخدم المرء:

import 'rc-slider/assets/index.css';

من المؤكد أنه من الممكن نسخ لصق ورقة الأنماط هذه في دليل static/ لكنها لن تظل متزامنة مع النمط الرئيسي في تحديث مكون مستقبلي ، ولا تتطابق مع ما توصي به وثائق هذا المكون.

المشكلة هي أن ملفات CSS هذه تقدم تأثيرات عالمية. نحن بحاجة إلى أن نكون قادرين على التقاط CSS ووضعه داخل دورة حياة React ، بحيث يتم فكها ، وعرضها على الخادم ، وما إلى ذلك.

تقوم العديد من المكتبات بذلك ، لكنني لا أعتقد أنه نمط جيد.

لست على دراية بالإجراءات الداخلية لـ Zeit Next ، ولكن هل يمكن استخدام بعض التحليلات الثابتة لـ import لتسجيل / التقاط CSS؟

يمكننا ذلك ، لكن سيكون الأمر غريبًا حقًا. مشابه لشيء خارج render() يدخل نفسه بطريقة سحرية داخل دورة حياة المكون الخاص بك.

// أحسب أنني سأشارك هذا مع أي شخص آخر

حسنًا ... لقد قضيت وقتًا طويلاً جدًا في محاولة اختراق CSS هنا ، لكنني توصلت إلى حل مناسب (بالنسبة لي). من المسلم به أنه اختراق ، لكن إعادة التحميل تعمل وكذلك البناء من جانب الخادم.

باستخدام (_shudder_) gulp ، مع ملف gulp هذا (https://gist.github.com/auser/25e88e39d83413773c01f4c000ec2806) يتم تجميع جميع ملفات **/*.scss معًا ودفعها إلى مكون Styles الذي أقوم بتركيبه الصفحة كعنصر "عادي".

آمل أن يساعد هذا شخصًا آخر حتى نتمكن من الحصول على دعم postcss حقيقي في المرة التالية.

شكرًا للاختراقauser ، لقد كنت أبحث في webpack config طوال اليوم دون أي حظ!

تعديل:
راجع للشغل ، تحتاج إلى إضافة محلل sass إلى ملف gulp!

نعم ولا ... أنا فقط استخدم الامتداد .scss كطريقة للتمييز بين ملفات css النقية والمجمعة مسبقًا. نظرًا لأن postcss (مع precss ) تحاكي sass جيدًا بما يكفي ، فليس لدي واحدة. لا تتردد في التعديل بنفسك باستخدام محلل sass.

يبدو أن هذا هو الحل الأفضل حاليًا ، باستخدام gulp لتجميع ملف css وإنشائه بشكل مضمّن أو حتى في / ثابت إذا كنت لا تمانع في عدم وجود إعادة تحميل ساخنة.

حصلت على استيراد css + إعادة التحميل السريع الذي يعمل بطريقة نظيفة. يتم استيراد css كسلسلة ويمكن للمستخدم تضمينها في الصفحة تمامًا مثل أي سلسلة أخرى. الرجاء إلقاء نظرة على هذا المثال ، وساعدني في الاختبار والعلاقات العامة مرحب بها!

https://github.com/davibe/next.js-css-global-style-test

أعتقد أن هذا المثال يجب أن يدخل في الأمثلة الرسمية لـ next.js. هل هو كذلك؟ rauchgarunodankzawa (آسف إذا قمت بوضع علامة على شخص ليس مشاركًا بشكل مباشر)

davibe شكرًا على العرض التوضيحي الخاص بك و babel-plugin-wrap-in-js

في المثال أرى استخدام ملف CSS وملف SCSS. هل تعرف ما إذا كان هذا سيعمل مع postcss و cssnext؟

@ khrome83 لا أرى لماذا لا ، أعتقد أنها مجرد مسألة تعديل .babelrc و next.config.js

davibe لقد اكتشفت أنه لم أتمكن من نشر تطبيقي بناءً على التكوين الخاص بك. لم يتمكن الإصدار من قراءة next/babel في الملف .babelrc . لقد قدمت مشكلة ، لكنني آمل حقًا أن يظهر حل من كل هذا. فقدان سهولة import file.css من create-react-app ، لكنني أعلم أنه يجب أن يكون هناك حل قادم :)

من المحتمل أن يكون الحل الذي أريده على هذا المنوال:

https://github.com/zeit/styled-jsx/pull/100#issuecomment -277133969

قد ندعم استيراد .css (عن طريق تحويله ببساطة إلى وحدة نمطية تصدر سلسلة) (وبالمثل قد ندعم .svg بتحويله إلى مكون رد فعل خالص)

وبالمثل قد ندعم .svg بتحويله إلى مكون رد فعل خالص

هذه خدعة بسيطة جدا. سأقوم بإنشاء مثال أساسي يوضح كيف تعاملت مع هذا في مشروع آخر =)

تحرير: انظر https://github.com/zeit/next.js/pull/982

بناءً على نموذج davibe ، قمت بإنشاء https://github.com/moxystudio/next.js-style-loader والذي نأمل أن يسهل إضافة ملفات css إلى مشاريع next.js. إنه مشابه لـ webpack's style-loader حيث أنه سيضيف / يزيل أوراق الأنماط أثناء تنقل المستخدم. كما أنه يدعم SSR.

إنه يعمل بشكل جيد مع css-loader (مع أو بدون وحدات css) ، postcss-loader ، sass-loader وربما أخرى. لاحظ أنه عند استخدام أداة تحميل css ، يجب تعيين الخيار url به على false beucase next.js الصور والخطوط وما إلى ذلك يجب أن تعيش /static . ستجد كل هذه المعلومات في README.

استمتع وأعطيني ملاحظات من فضلك!

شكرا على الريبو! عملت على استيراد ملفات css. أحاول استخدام blueprintjs ويبدو أن ملف css يتم تحميله بشكل صحيح! ومع ذلك ، يبدو أن قاعدة @ font-face التي يتضمنها css لا تعمل. :

--------------------تعديل----------------------

إنه يعمل في الواقع يا سيئ!
ومع ذلك ، لا يتم تحميل الرموز لأن توجيه nextjs افتراضيًا لا يسمح بعرض محتوى ثابت خارج / ثابت / والمسار النسبي يتسبب في الواقع في تحميله بمسار غير مسموح به.

pencilcheck نعم ، يجب عليك استخدام المسارات التي تشير إلى / ثابت ، ربما

هل هناك أي حل بديل فيما يتعلق بالمسار النسبي المضمّن في ملفات css مثل الخطوط atm؟ أو لا بد لي من نسخ ملفات الخطوط بالكامل و css إلى مجلد ثابت لكي يعمل؟

pencilcheck تحقق من أن ملفات CSS يمكن أن تظل خارج ثابت. يجب أن تكون صورك وخطوطك ثابتة داخلها وأن ترجع إليها بـ /static/file .

فهمتها. ومع ذلك ، فأنا أستخدم blueprint ، وهي حزمة npm ، أود ألا أضطر إلى تعديل أي ملفات داخل node_modules.

pencilcheck هذا غير ممكن للأسف. next.js صارم جدًا في كيفية تعامله مع الصور والأصول الأخرى. دعنا لا نلوث هذه المحادثة ويرجى إنشاء مشكلة في ريبو محمل النمط التالي إذا أمكنك ذلك.

tgoldenberg ، هل يمكنك وصف المشكلة بشكل أفضل أو إخباري بكيفية التكاثر؟ يرجى الرجوع إلى مستودعي. من الأسهل بالنسبة لي تتبع المشكلات هناك.

davibe ، انتهى الأمر بكونها مشكلة باستخدام yarn على npm install . كان الغزل يلقي ببعض الأخطاء التي لا يمكن تفسيرها ، ولكن بمجرد إزالتها ، كان المثال يعمل بشكل جيد في الإنتاج.

لقد أمضيت للتو 4 ساعات في محاولة إعداد هذا واعتقدت أنه قد يكون مفيدًا لأي شخص يتطلع إلى توفير بعض الوقت. يطبق الأنماط تلقائيًا عند التغيير (تمامًا كما في المثال الحالي) ، ويدير CSS من خلال PostCSS ويمنحك أسماء الوحدات المحلية من css-loader . كان عدم وجود هذا الأخير بمثابة كسر كبير للصفقات بالنسبة لي في الحالة الحالية لأمثلة "واردات css العالمية" / "css".

المكونات. js

import React from 'react';
import stylesheet from './styles.css';

const [css, className] = stylesheet;
const Component = () => (
    <p className={className.paragraph}>
        <Head><style dangerouslySetInnerHTML={{__html: css}} /></Head>
        bazinga
    </p>
);

.babelrc

{
    "presets": [
        "next/babel"
    ],
    "plugins": [
        ["wrap-in-js", {
            "extensions": ["css$"]
        }]
    ]
}

next.config.js
لاحظ الاختراق المذهل بـ exports-loader . يجب أن تكون هناك طريقة أفضل بالتأكيد ؟؟؟

module.exports = {
    webpack: (config) => {
        config.module.rules.push(
            {
                test: /\.css$/,
                use: [
                    {
                        loader: 'emit-file-loader',
                        options: {
                            name: 'dist/[path][name].[ext]'
                        }
                    },
                    {
                        loader: 'raw-loader'
                    },
                    {
                        loader: 'val-loader'
                    },
                    {
                        loader: 'exports-loader',
                        options: {
                            0: 'exports[0][1]',
                            1: 'exports.locals'
                        }
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true,
                            minimize: true
                        }
                    },
                    {
                        loader: 'postcss-loader'
                    }
                ]
            }
        );

        return config;
    }
};

لقد توصلت بنفسي إلى حل مشابه جدًا لما نشره satazor في موضع أعلى في الموضوع: https://github.com/jozanza/next-css-json-loader.

فقط أضف بضعة سطور إلى next.config.js :

module.exports = {
  webpack: config => {
    config.module.rules.push({
      test: /\.css$/,
      loader: 'emit-file-loader',
      options: {
        name: 'dist/[path][name].[ext]',
      }
    }, {
      test: /\.css$/,
      loader: 'babel-loader!next-css-json-loader',
    });
    return config;
  },
};

يتم استيراد الأنماط ككائنات js لذلك من السهل جدًا استخدامها مع glamor والحلول المشابهة:

// .css files now conveniently expose all styles as js objects
import styles from 'some-package/styles.css';
import { css } from 'glamor';
// ...
<div {...css(styles)}>
  this is a nice box. 
</div>

في صحتك! 🍻 :)

هل هناك طريقة لجعل هذا العمل لاستيراد ملفات markdown كسلاسل؟ أستخدم حاليًا أداة تحميل خام ، ولكن نظرًا لأنه مكون إضافي من حزمة الويب ، فإنه لا يعمل على الخادم.

تضمين التغريدة

لقد كتبت للتو ملحق بابل لاستيراد التخفيضات. على هاتفي المحمول الآن ، ولكن إذا قمت بعرض GitHub الخاص بي ، فسترى ذلك.

@ khrome83 هذا يبدو رائعا. نتطلع إلى أنها تحاول الخروج

شكرا لك @ khrome83! أنا سوف إعطائها بالرصاص

اضطررت إلى القيام بذلك بسرعة كبيرة ، لذلك لم أقم بتحديث الملف التمهيدي. لكنك تقوم فقط بتضمينه كمكوِّن إضافي بابل ، ثم استخدامه

استيراد ملف من 'File.md' ؛

حصلت عليه للعمل ، شكرا لك !! مفيد جدا

هذا بعيد المنال ولكن نظرًا لأن المشكلة مغلقة ، فلا تتردد في توضيح :)

بالنسبة إلى تخفيض السعر ، هناك شيئان يمكنك القيام بهما.

(1)
الأول هو تضمين ملف markdown كسلسلة ثم ترجمته إلى html / رد فعل في وقت التشغيل. يمكنك القيام بذلك باستخدام مُحمل babel wrap-in-js لتسجيله لامتداد ملف markdown تمامًا كما يتم استخدامه في المثال next.js examples/with-globa-stylesheet/.babelrc لـ css.

(2)
شيء آخر يمكنك القيام به هو ترجمة تخفيض السعر في وقت الترجمة باستخدام markdown-in-js
قد يكون هذا أكثر إثارة للاهتمام في بعض السيناريوهات لأن مستند تخفيض السعر مقدم مسبقًا ، وبالتالي يكون أسرع في وقت التشغيل (يقوم فقط بتنفيذ js). أيضًا ، تسمح لك المكتبة بإصابة مكونات React المخصصة. لسوء الحظ في هذه الحالة ، يجب عليك كتابة تخفيض السعر مضمنًا في source.js هكذا .

إذا اخترت (2) فاعلم أيضًا أن هناك مكونًا إضافيًا لـ atom يوفر بناء الجملة hilight لبناء جملة markdown-in-js ويسمى language-markdown-in-js

davibe شكرا لك على النصيحة! أفضل أن يتم تحليل الشطب على أنه وقت إنشاء ، ولكن المشكلة الوحيدة التي أواجهها مع markdown-in-js هي الهروب من backticks أثناء التأليف :(. ربما يجب أن أحاول الاستيراد كسلسلة باستخدام babel ثم إدخال ذلك إلى markdown-in-js ؟

تضمين التغريدة

هناك عمليات تخفيض السعر لها. كان السبب في أنني كتبت المكون الإضافي الخاص بي هو نفس الشيء. أقوم بسحب علامة التخفيض كسلسلة ، ثم أقوم بتشغيلها من خلال رد الفعل - تخفيض السعر يعمل هذا بشكل جيد لأنني أستطيع تمرير مكونات التفاعل لتمثيل قطع تصيير العلامات ، مثل مكون القائمة للتعامل مع جميع القوائم. يعمل بشكل جيد مع Styled JSX.

هل هناك أي تحديث على ذلك؟ من خلال التعليقات أعلاه ، أرى أنه لا يوجد حتى الآن حلول مثالية.
تضمين التغريدة
هل من الممكن الحصول على مثال باستخدام أداة تحميل ذات نمط متماثل - https://www.npmjs.com/package/isomorphic-style-loader؟

سيكون ذلك مثاليًا!

هل لدى أي شخص حل عند استيراد مكون رد فعل من حزمة npm يقوم بدوره باستيراد ملف .css أو .scss؟ لذلك يتم استيراد الملفات من node_modules بشكل أساسي

لقد كنت أستخدم Create-React-App (CRA) لبضعة أسابيع ، لكنني صادفت اليوم Next.js وكنت متحمسًا جدًا لأن CRA لا تدعم حاليًا العرض من جانب الخادم (SSR) وهو أمر مخزٍ حقًا.
أرغب في التبديل إلى Next.js للحصول على دعم SSR خارج الصندوق ولكن عدم القدرة على استيراد ملفات .scss يعيقني.
هل وجد أي شخص طريقة لإضافة محمل SASS إلى تهيئة Webpack؟

متفقًا مع cr101 ، عدم وجود دعم لـ CSS / SASS يعني أنه يجب علي التخلص من أطر css مثل الأساس الذي لا يعد خيارًا بالنسبة لي.

كنت أستخدم الريبو الذي قدمته davibe لكنه لم يعد يحافظ عليه ، وأحدث مع الحل الذي لديه .

سأحب إذا وجد شخص ما حلاً لهذا. كان التحديث إلى 2.4.1 ضروريًا للغاية بسبب خطأ في الأمان ، لذلك ليس لدي خيار العودة إلى الأسفل.

MustafaHosny اللهم امين يارب أعتقد بصراحة أن التالي رائع حقًا أن تكون قادرًا على العمل خارج الصندوق. كل شيء على ما يرام حتى البنية المشفرة (مثل الدليل الإلزامي /pages ، /static إلخ). لكن الوحدات غير المدعومة تمامًا scss تحطم كل شيء بالنسبة لنا. لدينا بنية scss معقدة للغاية مع نقاط توقف تلقائية وإعادة حساب نسبة العرض إلى الارتفاع لكل شيء. لقد عملنا بجد لجعل هيكلنا مثاليًا للغاية. التالي هو أن تكون كبيرة لا نستطيع مجرد التخلص من كل scss الاشياء التي لدينا في الوقت الراهن من الوجود. غير المدعوم scss هو الشيء الوحيد ولكن الأكثر أهمية الذي يمنعنا من الترحيل إلى هذه الأداة الجميلة.

في الواقع ، # 1615 - هناك بعض الإجراءات جارية. timmywil يحاول إعداد isomorphic-style-loader للعمل مع next . كل من يهتم مرحب به للانضمام والمشاركة.

لقد جربت كل الحلول التي يشير إليها هذا الخيط ، ومع ذلك يمكن أن تجعل أيًا منها يعمل. لذلك قررت أن أحاول أن أبذل قصارى جهدي وقمت بتوثيقها هنا

almeynman شكرا لك! بالتأكيد سوف نرى في نهجك!
بالمناسبة ، تمكنت من جعل الوحدات النمطية scss تعمل باتباع هذا المثال. كل ما قمت به هو إضافة sass-loader وتمكين خرائط المصادر.

تمكنت من الحصول على next.js suport CSS (حتى SCSS) بهذه الطريقة.

أولاً ، في next.config.js ، قم بتعديل webpack config عن طريق إضافة أدوات تحميل معينة ومثيل DefintPlugin .

const webpack = require('webpack');

module.exports = {
  webpack: (config, {dev}) => {
    config.module.rules.push({
      test: /\.scss$/,
      use: [
        'style-loader',
        'css-loader',
        'sass-loader'
      ],
      exclude: /node_modules/,
    });

    config.plugins.push(
      new webpack.DefinePlugin({
        "process.env": {
          // flag to indicate this is for browser-side
          BROWSER: JSON.stringify(true),
       }
      })
    );

    return config;
  }
};

بعد ذلك ، في كود المكون ، تتطلب ملف النمط بشرط. فهو يتأكد من أن الحزم الجانبية للمتصفح فقط هي التي تحتوي على وحدة نمط.

if (process.env.BROWSER) {
  require("./style.scss");
}

إذا كنت لا تمانع في الحصول على if (process.env.BROWSER) ، فهو يعمل بشكل مثالي.

نهج جيد هنا

almeynman IMO هذا ليس أسلوبًا جيدًا للغاية لأنك تقوم بتحميل كود CSS لموقع الويب بأكمله على كل صفحة بدلاً من تحميل أنماط CSS ذات الصلة بتلك الصفحة فقط.
فقط استيراد ملفات .scss التي تحتاجها بدلاً من CSS لموقع الويب بالكامل من شأنه تقليل حجم الصفحات بشكل كبير عن طريق تحميل كود CSS الذي تحتاجه فقط.

@ cr101 مرحبًا ، لم أكن أعرف ذلك. لم أستخدم هذا الإعداد حقًا ، لقد قمت بنشره كمرجع للآخرين (اعتقدت أنه جيد ...). ما زلت أستخدم أسلوبي الموضح في منشور المدونة . إذا كان بإمكانك إعطائي بعض التعليقات حول هذا الإعداد ، فسيكون ذلك رائعًا

المزيد من الأمثلة والمناقشات إذا كان أي شخص مهتمًا:

https://github.com/iaincollins/nextjs-starter
https://github.com/zeit/next.js/issues/2534
https://github.com/zeit/next.js/tree/v3-beta/examples/with-global-stylesheet

بناءً على ما سبق وهذا الموضوع ، تمكنت من استخدام PostCSS لتحويل:

  • ملف SCSS العالمي (الوحدات النمطية هي نفسها ، فأنت تحتاج فقط إلى نقطة دخول لتجميع كل CSS للإنتاج مسبقًا).
  • افصل CSS لجهة خارجية بخطوط مخصصة مشار إليها من خلال عنوان URL النسبي (يتم حلها من خلال تضمين السحر).

في ملف CSS واحد بسعر /static/styles/app.css للعمل في الإنتاج ، مع استمرار عمل إعادة التحميل السريع. لاحظ استخدام styled-jsx ولكن يمكن إجراؤه بدون ذلك باستخدام <style dangerouslySetInnerHTML={} />

postcss.config.js

module.exports = {
  plugins: [
    require("postcss-easy-import")({ prefix: "_" }), // keep this first
    require("postcss-url")({ url: "inline" })
  ]
};

next.config.js

أدوات التحميل لتحويل ملفات .scs في وضع dev لإعادة التحميل السريع واستخراجها إلى ملف .css واحد في المنتج. هذا يعطيني build/app.css لذا عند بناء الإنتاج ، أضفت cp build/app.css static/styles/app.css بعد next build لإتاحته في التصدير الثابت و تضمينه في رأس مخصص كما هو موضح أدناه.

const ExtractTextPlugin = require('extract-text-webpack-plugin');

export default {
  webpack: (config, { dev }) => ({
    ...config,
    module: {
      ...config.module,
      rules: [
        ...config.module.rules,
        {
          test: /\.(css|scss)/,
          loader: 'emit-file-loader',
          options: {
            name: 'dist/[path][name].[ext]'
          }
        },
        ...(dev
          ? [
              {
                test: /\.css$/,
                use: ['raw-loader', 'postcss-loader']
              },
              {
                test: /\.s(a|c)ss$/,
                use: [
                  'raw-loader',
                  {
                    loader: 'postcss-loader',
                    options: {
                      sourceMap: true
                    }
                  },
                  {
                    loader: 'sass-loader',
                    options: {
                      sourceMap: true
                    }                    
                  }
                ]
              }
            ]
          : [
              {
                test: /\.(css|scss)/,
                use: ExtractTextPlugin.extract({
                  use: [
                    {
                      loader: 'css-loader',
                      options: {
                        importLoaders: 2,
                        modules: false,
                        url: true,
                        minimize: true,
                        localIdentName: '[hash:base64:5]'
                      }
                    },
                    {
                      loader: 'postcss-loader'
                    },
                    {
                      loader: 'sass-loader'
                    }
                  ]
                })
              }
            ]),
        {
          test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
          loader: 'url-loader?limit=100000&&name=[name].[ext]?[hash:8]'
        }
      ]
    },
    plugins: [
      ...config.plugins,
      ...(dev ? [] : [new ExtractTextPlugin('app.css')])
    ]
  }),
};

رأس مخصص

const inlineCSS =
  process.env.NODE_ENV !== ENV_PRODUCTION && require('styles/index.scss');
...
      <Head>
        {inlineCSS && <style jsx global> {__html: inlineCSS} </style>}
          {process.env.NODE_ENV === ENV_PRODUCTION &&
            <link
              rel="stylesheet"
              type="text/css"
              href={`/static/styles/app.css?${this.props
                .__NEXT_DATA__.buildId}`}
            />}
      </Head>

أتمنى أن يساعدك هذا. اسمحوا لي أن أعرف إذا كان أي شخص يحتاج إلى مزيد من التوضيح. نتطلع إلى المزيد من الحلول كذلك. نأمل أن يتمكن شخص ما من التوصل إلى مكون إضافي جيد في النهاية لأنه لا يزال تكاملًا صعبًا وعنيفًا.

بدلاً من استخراج كل ملفاتك .scss ملف CSS واحد ، سيكون من الأفضل تجميع كل ملف مستورد .scss في ملف CSS الخاص به. بهذه الطريقة سوف تقوم فقط بتحميل أنماط CSS التي تحتاجها في كل صفحة.
لست متأكدًا من كيفية القيام بذلك بالرغم من ذلك.

يرجى التحقق من طلب السحب الخاص بي ، أعتقد أن لدي حلًا جيدًا:
https://github.com/zeit/next.js/pull/2638

@ cr101 هذا صحيح في الواقع. نحن نستورد مكتبة واجهة المستخدم الداخلية الخاصة بنا إلى مشاريع مختلفة ، ومن ثم هناك دائمًا جزء كبير من الملف المراد تحميله (ليس مثاليًا أعرفه ، وما زلت أعمل على تشكيل هذا الوحش). ستكون الخطوة التالية من compile and serve 1 file إلى X number of files at X locations . يصبح الأمر أكثر تعقيدًا عندما تضع في اعتبارها المفاضلات من اقتحام أجزاء CSS أصغر مقابل الإصدارات الخارجية القابلة للتقسيم والأداء المستضافة على CDN ، لذا أعتقد أنها ستكون ممتعة ولكنها تتضمن مشروعًا بمفرده. تحرير - بالتأكيد خارج نطاق ما من المفترض أن يتعامل معه Next ، أفضل ما يجب أن نهدف إليه هو المكون الإضافي أو النمط التالي.

لست متأكدًا مما إذا كان هذا به أي مشكلة في الأداء ، ولكن هذا حل بسيط جدًا إذا كنت تستخدم مكونات نمطية أو ما شابه ذلك ، فقط قم بإنشاء غلاف CSS:

import styled from 'styled-components';

const Collapse = props => (
  <__Collapse>
    { props.children }
  </__Collapse>
);

export default Collapse;

/**
 * CSS
 */
const __Collapse = styled.div`
  .rc-collapse {
    background-color: #f7f7f7;
    border-radius: 3px;
    border: 1px solid #d9d9d9;
  }
  ...
`;
import RcCollapse from 'rc-collapse';
import Collapse from '~/components/rc/Collapse';

const HelpPage = () => (
  <Collapse>
    <RcCollapse>
      <RcCollapse.Panel header="Title">Content</RcCollapse.Panel>
    </RcCollapse>
  </Collapse>
);

الشيء الذي يعجبني في هذا الأسلوب هو أنه يمكنني التخصيص من مصدر CSS (وهو ما أحتاج إلى القيام به في معظم الأوقات على أي حال) ، دون الحاجة إلى كتابة تجاوزات فوق القواعد الأصلية إذا قمت باستيراد .css ملف من node_modules .

إليك حل بسيط لاستيراد ملفات CSS باستخدام babel-plugin-inline-import :

.babelrc

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "inline-import",
      {
        "extensions": [".css"]
      }
    ]
  ]
}

الصفحة / المكون

import "prismjs";

import { PrismCode } from "react-prism";
import prismGlobalStyles from "prismjs/themes/prism.css";

export default () => {
    return (
        <div>
            <style global jsx>
                {prismGlobalStyles}
            </style>
            <PrismCode className="language-javascript">
                {`function(noop) {
                    return noop;
                }`}
            </PrismCode>
            {/* ... */}
        </div>
    );
};

stovmascript ، هذا حل جميل ولكن ما زلت أحصل على أخطاء (أقوم باستيراد إصدار .css من https://github.com/Hacker0x01/react-datepicker). هل أنت متأكد من أنه ليس لديك أي شيء آخر يلعب هنا؟ من الأخطاء ، يبدو أنه يحتاج إلى مستوى آخر من تحميل CSS.

@ hilarykitz ، حل stovmascript يعمل معي ، هل يمكنك أن ترسل لنا الخطأ الذي تحصل عليه؟

stovmascript - كيف تتخلص من مخبأ بابل.

  1. اصنع ملف CSS
  2. استيراد ملف
  3. تطبيق
  4. تغيير ملف CSS - إضافة محدد ونمط جديدين
  5. شاهد أن Babel Cache يحتفظ بالنسخة القديمة

@ khrome83 ستحتاج إلى مسح node_modules / .cache

لقد وجدت حلاً أفضل باستخدام المكون الإضافي babel-inline-loader الذي يمسح ذاكرة التخزين المؤقت ويعمل مع ما سبق. تكمن المشكلة في هذه الطريقة في أنه يمكنك فقط تطبيق الأنماط العامة. عند استخدام علامة غير <style jsx global> ، فلن تضيف data-jsx بشكل صحيح مما يؤدي إلى هزيمة الغرض.

لقد وجدت حلاً أفضل باستخدام المكون الإضافي babel-inline-loader الذي يمسح ذاكرة التخزين المؤقت ويعمل مع ما سبق. تكمن المشكلة في هذه الطريقة في أنه يمكنك فقط تطبيق الأنماط العامة. عند استخدام في غير

أضفت مثالاً باستخدام حل stovmascript :

https://github.com/zeit/next.js/pull/3157

كيف تقوم بتضمين أكثر من css خارجي؟
أستخدم 2 libs التي تتطلب ذلك في نفس المكون ، كل واحد يعمل بشكل منفصل ، لكنني لا أعرف كيفية الجمع بينهما.

import rtStyle from 'react-table/react-table.css';
import dpStyle from 'react-datepicker/dist/react-datepicker.css';
...
render() {
    return (
      <div>
        {/* <style jsx global>{ rtStyle }</style> */}
        <style jsx global>{ dpStyle }</style>
...

CHarnel حاول <style jsx global>{ rtStyle }{dpStyle}</style>

almeynman الحصول على هذا:

Module build failed: SyntaxError: C:/.../components/activeUsersTable.js: 
Expected one child under JSX Style tag, but got 2 (eg: <style jsx>{`hi`}</style>)

@ CHarnel حاول وضع كلاهما في سلسلة القالب

@ CHarnel جرب هذا النهج
<style jsx global>{ $ {rtStyle} $ {dpStyle} }</style>

تضمين التغريدة

أحاول وضع هذه المغلق في ملف js واحد وتصديرها

import bootstrap from 'bootstrap/dist/css/bootstrap.min.css'
import styles from './index.css'

export default bootstrap + styles

وبعد ذلك فقط

import styles from '../styles'
...
<style jsx global>{styles}</style>

باستخدام https://github.com/sheerun/extracted-loader الذي قمت بإنشائه ، يمكنك استخدام ExtractTextPlugin لكل من التطوير والإنتاج ، ولا حاجة إلى html مختلف في التطوير أو حقن css في js.

comus لقد استخدمت

sheerun جميل ، شكرا لك

لقد قدمت مثالًا أكثر شمولاً إلى next.js:
https://github.com/zeit/next.js/pull/3451

كان هذا يعمل قبل nextjs v4

<style jsx global>{style}</style> <style jsx global>{colors}</style> <style jsx global>{layout}</style>

ما سبب استخدام هذا aproach لتحميل أنماط jsx العامة؟ <style jsx global>{ rtStyle }{dpStyle}</style>

لقد جعلت نفسي حلاً يعتمد على emit-files-loader . إذا كان أي شخص مهتمًا ، فيمكنني نشره هنا ، لكنه يعتمد على إعداد خادم مخصص - تحتاج أساسًا إلى أن تكون قادرًا على تقديم دليل واحد بشكل ثابت داخل .next build dir. ربما يمكن تهيئته بدون خادم بالاعتماد على بنية مسار /_next/... للخادم.

بخلاف ذلك يمكنك كتابة import stylesheet from './styles/style.[scss|less|stylus|w/e]'; وسيكون المسار العام لملف الأنماط الخاص بك ، لذا يمكنك وضعه في <link> . يتضمن ?[hash] للتخزين المؤقت الدائم ويقوم بإعادة التحميل السريع.

وسيتم عرضnikolakanacki الدعم الرسمي قريبا جدا 🙏 https://github.com/zeit/next.js/pull/3578

timneutkens لقد رأيت هذا ، هل هناك تقدير لـ "قريب جدًا"؟ أرى أنه في الكناري بالفعل.
كنت بحاجة للتو إلى حل على الفور ، وقضيت يومين إلى ثلاثة أيام في البحث عن حل ، وتمكنت من كتابة حل خاص بي وهو في الأساس "حل سهل". حتى أنني أفكر في دمجه مع extract-text-webpack-plugin بحيث يمكن للمرء أن ينضم بشكل ثابت إلى جميع ملفات .[css|stylus|less|scss] المنفصلة وجعلها جميعًا متاحة كمورد ثابت واحد كما هو الحال عادةً بدون التالي.

أعتقد أن المشكلة الرئيسية وراء هذه المشكلات هي أن هناك الكثير من "السحر" يحدث في الخلفية وراء عمليات الإنتاج والتطوير ، مع إعادة التحميل الساخنة والأشياء ... ربما يمكن للمرء قراءة المصدر ومعرفة كيفية تجميع الأشياء معًا ، ولكن سيكون أمرًا رائعًا إذا كتب أحد الأشخاص الذين قاموا بإنشائه بعض المستندات حول ذلك ، أعتقد أن المزيد من الأشخاص يمكنهم المساهمة.

nikolakanacki قريبا جدا 🙏 🤐

حتى أنني أفكر في دمجه مع Extract-text-webpack-plugin الإضافي بحيث يمكن للمرء أن ينضم بشكل ثابت إلى جميع ملفات. [css | stylus | less | scss] وجعلها جميعًا متاحة كمورد ثابت واحد كما هو الحال عادةً بدون التالي .

الإضافات التي كتبتها للإصدار الخامس التالي تفعل ذلك بالفعل ، وسيتم فتحها قريبًا 👍

فيما يتعلق بكتابة المستندات على الأجزاء الداخلية ، نخطط لتوثيق كيفية عمل كل شيء بعد خروج الإصدار الخامس 🙏

timneutkens شكرا لك!

timneutkens شكرًا لك على التحديث ، يرجى نشر تحديث هنا عندما يصل هذا الشيء!

أي أخبار عن هذا؟

لست متأكدًا من الأخبار الأخرى التي تتوقعها 🤔

تم إصدار هذا في Next.js v5.
حتى أنه في الملف التمهيدي https://github.com/zeit/next.js#importing -css - sass - less - stylus-files

أيضًا ، تم دمج PR المذكور وإغلاق هذه المشكلة.

فقط قم بإنشاء / مجلد ثابت في مشروع الجذر ، ثم ضع file.css داخل / static ، ثم إلى Header html Structure.

import Head from 'next/head';
<Head>
          <meta charset="utf-8" />
          <link rel="stylesheet" href="/static/css/custom.css" />
</Head>

ثم استخدم className في أي مكان!

comus

الكثير من الشمولية والذكية .. أشكركم على هذا .. لقد كنت أبحث عن هذا النوع من الحلول طوال اليوم ..

ما عليك سوى إنشاء / مجلد ثابت في مشروع الجذر ، ووضع file.css داخل / ثابت ، ثم إلى Header html Structure hock.

import Head from 'next/head';
<Head>
          <meta charset="utf-8" />
          <link rel="stylesheet" href="/static/css/custom.css" />
</Head>

ثم استخدم className في أي مكان!

قم بإنشاء مجلد "عام" في جذر التطبيق الخاص بك (حيث يوجد ملف package.json).

تمت إضافة الدعم عبر # 8626!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات