Next.js: Mengimpor file CSS?

Dibuat pada 27 Des 2016  ·  102Komentar  ·  Sumber: vercel/next.js

Terkadang menyenangkan untuk memecah CSS Anda menjadi file .css . Saya sudah mencoba melakukan hal berikut:

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

Kemudian di index.js, saya sudah mencoba melakukan:

import css from './index.css'

Dan di next.config.js:

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

Tapi sayangnya, itu terus memberi saya:

 ERROR  Failed to compile with 1 errors

This dependency was not found in node_modules:

* ./index.css

Sepertinya itu tidak menyelesaikan ke tempat yang tepat karena alasan tertentu, component.js berfungsi meskipun melalui import component from './component.js' , jadi saya tidak yakin apa yang terjadi di sini.

Komentar yang paling membantu

Berikut solusi sederhana untuk mengimpor file CSS menggunakan babel-plugin-inline-import :

.babelrc

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

halaman / komponen

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>
    );
};

Semua 102 komentar

Maksud Anda ini tidak berfungsi di server?
Saya pikir kami belum memiliki solusi untuk ini. cc @ aroda

oh benar, saya rasa perlu ada cara untuk konfigurasi webpack di next.config.js untuk bekerja di kedua sisi agar ini berfungsi.

Saya memiliki masalah yang hampir sama karena saya tidak bisa mendapatkan Next untuk bermain bagus dengan CSS atau SASS. Saya memiliki direktori components dengan komponen React standar yang saya impor ke halaman saya tetapi setiap kali saya mencoba mengimpor dalam file SASS (atau CSS) saya mendapatkan ~ "Anda perlu menggunakan loader yang sesuai untuk file ini" ketik pesan kesalahan.

Umumnya di React saya mengimpor file SASS dan mengkompilasi Webpack menggunakan style, css dan sass loader. Saya mencoba untuk menambahkan ini ke file next.config.js (dan NPM menginstalnya) tetapi masih mendapatkan pesan kesalahan yang sama.

File next.config.js :

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

Maaf jika pertanyaan ini terdengar bodoh atau saya melewatkan sesuatu yang jelas di dokumen yang menjelaskan jawabannya, tetapi jika ada yang memiliki contoh yang berfungsi untuk mengimpor / mengompilasi SASS (atau setidaknya CSS) ke dalam komponen atau halaman dengan apa pun yang perlu ditambahkan ke next.config.js untuk memuat / mengkompilasinya, saya akan sangat menghargainya. Terima kasih!

Saya menggunakan css-modules-require-hook
agar css berfungsi.

@spacedragon Apakah Anda memiliki contoh bagaimana mengintegrasikan css-modules-require-hook dengan Next.js? Saya mengalami masalah dalam membuatnya berfungsi.

Saya masih mengalami masalah dengan mendapatkan SASS untuk dikompilasi jika ada yang dapat menjelaskan cara melakukan ini atau hanya mengimpor file CSS di dalam Berikutnya itu akan dihargai (melalui contoh kode).

Menarik bahwa file README telah diperbarui untuk menghapus contoh pemuat SVG dan diubah menjadi mengatakan menambahkan pemuat untuk file seperti SVG, CSS dan SASS tidak disarankan. Saya tidak yakin mengapa CSS sebaris tidak masalah tetapi CSS yang diimpor tidak, tetapi saya yakin ada alasan bagus mengapa. Saat ini saya tidak yakin tentang strategi terbaik untuk menangani tidak ada CSS dan SASS yang ditentukan / sebaris JS.

@MikeDigitize Lihat komentar di # 627 dan # 638.

Sebenarnya mungkin dan cukup mudah untuk memproses gaya di sisi server.

langsung di node:

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

melalui register babel:

// 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"]
});

melalui pemuat webpack:

Saya pribadi menggunakan isomorphic-style-loader karena memungkinkan saya untuk menyebariskan CSS penting saat melakukan rendering di server. Reload panas dan hal-hal terkait DX lainnya juga berfungsi. Saya bukan penggemar CSS di JS karena memperumit penggunaan komponen pihak ke-3 dan dan entah bagaimana menghilangkan C dari CSS.

@viktorbezdek Apakah Anda telah berhasil menggunakan isomorphic-style-loader dengan next.js?

@noeljackson Tidak juga, tapi saya berniat untuk. Next.js terlihat menjanjikan dan bisa menghemat banyak waktu saya jika saya membuatnya bekerja. Akan memeriksanya dalam satu atau dua minggu ke depan dan mengirimkan permintaan penarikan jika saya berhasil.

@viktorbezdek Saya akan memberikan hadiah untuk yang satu ini, karena ini sangat penting untuk proyek yang sedang saya kerjakan. Saya tahu saya bukan orang yang tidak kompeten, tetapi saya tidak mengerti cara cukup men-debug transformasi babel untuk mengetahui hal ini. Saya telah mencoba permutasi ide-ide ini dan tidak ada yang berhasil 100%. Saya bisa mendapatkan raw-loader untuk menarik stylesheet yang dikodekan data menggunakan babel-plugin-webpack-loader, tetapi tidak ada pemuat gaya yang berfungsi. Terima kasih telah bergabung! :) Sangat dihargai.

Apakah ada solusi untuk ini? Saya ingin melihat solusinya sehingga saya tidak perlu menyertakan css secara global.

FWIW, saya baru saja meletakkan file CSS saya di folder /static . Colocation tidak bagus, tapi bukan masalah besar juga.

Akan ada solusi. Saya hanya tidak berhasil menyelesaikannya. Saya telah membuat prototipe pertama secara lokal yang tampaknya berfungsi, namun perlu beberapa jam untuk diselesaikan. Saya cukup yakin saya akan selesai setelah akhir pekan. Tetap disini.

@ Matthewmueller Anda menggunakan modul CSS?

@viktorbezdek Terima kasih telah mengerjakan ini! Dukungan Modul CSS (atau serupa) penting untuk IMO proyek ini. Jsx dengan gaya, tidak masalah untuk situasi sederhana tetapi sulit dibaca untuk komponen yang sangat bergaya.

Akankah plugin babel seperti ini menjadi opsi (sisi server juga)? https://github.com/gajus/babel-plugin-react-css-modules

Saya mencoba membuat ini berfungsi tetapi tidak berhasil: /

Saya mendapat modul CSS yang berfungsi dengan babel-plugin-css-modules-transform . Lihat contoh hacky saya di

Kelemahannya adalah Anda harus mematikan server & memulai ulang setiap kali Anda melakukan perubahan pada CSS.

Beberapa komponen React menampilkan gaya default melalui sumber daya statis import . Misalnya untuk mengimpor gaya default https://github.com/react-component/slider, seseorang akan menggunakan:

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

Memang mungkin untuk menyalin dan menempelkan lembar gaya ini di direktori static/ tetapi tidak akan tetap sinkron dengan gaya hulu pada pembaruan komponen di masa mendatang, dan tidak cocok dengan rekomendasi dokumentasi komponen ini.

Masalahnya adalah file-file CSS tersebut memperkenalkan efek global. Kita harus bisa _capture_ CSS dan memasukkannya ke dalam siklus hidup React, sehingga itu dilepas, dirender server, dll.

Banyak perpustakaan melakukan itu, tapi menurut saya itu bukan pola yang baik.

Saya tidak terbiasa dengan internal Zeit Next, tetapi dapatkah beberapa analisis statis dari import digunakan untuk mendaftarkan / menangkap CSS?

Kami bisa, tapi itu akan sangat aneh. Mirip dengan sesuatu di luar render() secara ajaib memasukkan dirinya ke dalam siklus hidup komponen Anda.

// Kupikir aku akan membagikan ini untuk orang lain

Yah ... Saya menghabiskan terlalu banyak waktu mencoba meretas CSS di sini, TAPI saya mendapatkan solusi yang berhasil (untuk saya). Memang, ini adalah retasan, tetapi hot reload berfungsi dan begitu pula pembangunan sisi server.

Menggunakan (_shudder_) teguk, dengan gulpfile ini (https://gist.github.com/auser/25e88e39d83413773c01f4c000ec2806) semua **/*.scss file digabungkan bersama dan dimasukkan ke dalam komponen Styles yang saya pasang halaman sebagai elemen "normal".

Semoga ini bisa membantu orang lain sampai kita bisa mendapatkan dukungan postcs yang sebenarnya di kemudian hari.

Terima kasih untuk hack @auser , saya telah melihat konfigurasi webpack sepanjang hari tanpa hasil!

Edit:
Btw, Anda perlu menambahkan parser sass ke gulpfile!

Ya dan tidak ... Saya hanya menggunakan ekstensi .scss sebagai cara untuk membedakan file css murni dari yang telah dikompilasi sebelumnya. Sejak postcs (dengan precss ) meniru sass dengan cukup baik, saya tidak memilikinya. Jangan ragu untuk mengedit sendiri dengan pengurai sass.

Sepertinya itu adalah solusi terbaik saat ini, menggunakan gulp untuk mengkompilasi file css dan membangunnya secara inline atau bahkan di / static jika Anda tidak keberatan tidak memuat ulang panas.

Saya mendapat css import + hot reload bekerja dengan cara yang bersih. Css diimpor sebagai string dan pengguna dapat menyebariskannya di halaman seperti string lainnya. Silakan lihat contoh ini, bantu saya menguji dan PR dipersilakan!

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

Saya percaya contoh ini harus membuatnya menjadi contoh resmi next.js. Melakukannya? @rauchg @arunoda @nkzawa (maaf jika saya menandai seseorang yang tidak terlibat langsung)

@davibe terima kasih atas demo dan babel-plugin-wrap-in-js Anda

Dalam contoh saya melihat penggunaan file CSS, dan file SCSS. Apakah Anda tahu apakah ini akan bekerja dengan postcss & cssnext?

@ khrome83 Saya tidak mengerti mengapa tidak, saya pikir ini hanya masalah menyesuaikan .babelrc dan next.config.js

@davibe Saya menemukan bahwa saya tidak dapat menerapkan aplikasi saya berdasarkan konfigurasi Anda. Bangunan tidak dapat membaca next/babel dalam file .babelrc . Saya mengajukan masalah, tetapi saya sangat berharap bahwa solusi akan muncul dari semua ini. Kehilangan kemudahan import file.css dari create-react-app , tetapi saya tahu pasti ada solusi yang akan datang :)

Solusi yang saya inginkan kemungkinan besar seperti ini:

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

Kami mungkin mendukung pengimporan .css (dengan hanya mentranspilasinya ke dalam modul yang mengekspor string) (dan juga kami dapat mendukung .svg dengan memindahkannya ke dalam komponen reaksi murni)

dan juga kita dapat mendukung .svg dengan mentranspilasinya menjadi komponen react murni

Ini adalah trik yang cukup sederhana. Saya akan membuat contoh dasar yang menunjukkan bagaimana saya menangani ini di proyek lain =)

EDIT: lihat https://github.com/zeit/next.js/pull/982

Berdasarkan contoh @davibe, saya telah membuat https://github.com/moxystudio/next.js-style-loader yang diharapkan akan memudahkan penambahan file css ke dalam proyek next.js. Ini mirip dengan style-loader webpack yang akan menambah / menghapus lembar gaya saat pengguna menavigasi. Ini juga mendukung SSR.

Ini bekerja dengan baik dengan css-loader (dengan dan tanpa modul css), postcss-loader , sass-loader dan mungkin lainnya. Perhatikan bahwa ketika css-loader digunakan, opsi url harus disetel ke false beucase next.js gambar, font, dll harus hidup /static . Anda akan menemukan semua informasi ini di README.

Selamat menikmati dan tolong beri saya umpan balik!

Terima kasih atas reponya! Ini berfungsi untuk mengimpor file css. Saya mencoba blueprintjs dan sepertinya css dimuat dengan benar! Namun aturan @ font-face yang disertakan dalam css tampaknya tidak berfungsi. :

-------------------- edit ----------------------

Ini benar-benar bekerja, salahku!
Namun ikon tidak dimuat karena perutean nextjs secara default tidak mengizinkan penayangan konten statis di luar / static / dan jalur relatif benar-benar menyebabkannya dimuat dengan jalur yang tidak diizinkan.

@pencilcheck ya Anda harus menggunakan jalur yang menunjuk ke / statis, mungkin saya akan membuatnya lebih jelas di README.

Apakah ada solusi terkait jalur relatif yang disertakan dalam file css seperti font atm? Atau saya hanya perlu menyalin seluruh file font dan css ke folder statis agar bisa berfungsi?

@pencilcheck file CSS dapat tetap berada di luar statis. Gambar dan font Anda harus di dalam statis dan Anda mereferensikannya dengan /static/file .

Saya mengerti. Namun saya menggunakan cetak biru, yang merupakan paket npm, saya ingin tidak perlu mengubah file apa pun di dalam node_modules.

@pensil Sayangnya itu tidak mungkin. next.js sangat ketat dalam cara menangani gambar dan aset lainnya. Jangan mencemari percakapan ini dan buat masalah di repo pemuat gaya-berikutnya jika Anda bisa.

@tgoldenberg dapatkah Anda menjelaskan masalah dengan lebih baik atau beri tahu saya cara mereproduksi? silakan lihat repositori saya. Lebih mudah bagi saya untuk melacak masalah di sana.

@davibe , ini berakhir dengan masalah menggunakan yarn lebih dari npm install . Yarn melakukan beberapa kesalahan yang tidak bisa dijelaskan, tetapi setelah saya menghapusnya, contoh tersebut bekerja dengan baik dalam produksi.

Saya hanya menghabiskan 4 jam mencoba mengatur ini dan berpikir mungkin menarik bagi siapa saja yang ingin menghemat waktu. Ini menerapkan gaya secara otomatis saat diubah (seperti dalam contoh saat ini), menjalankan CSS melalui PostCSS dan memberi Anda nama modul lokal dari css-loader . Kekurangan yang terakhir ini adalah pemecah kesepakatan utama bagi saya dalam kondisi contoh "css global" / "impor css" saat ini.

component.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
Perhatikan peretasan luar biasa dengan exports-loader . Pasti ada cara yang lebih baik, tentunya ???

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;
    }
};

Saya menemukan solusi sendiri, yang sangat mirip dengan apa yang diposting @satazor lebih tinggi di utas: https://github.com/jozanza/next-css-json-loader.

Cukup tambahkan beberapa baris ke 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;
  },
};

Gaya diimpor sebagai objek js sehingga sangat mudah digunakan dengan glamor dan solusi serupa:

// .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>

Bersulang! 🍻 :)

Apakah ada cara untuk membuat ini berfungsi untuk mengimpor file penurunan harga sebagai string? Saat ini saya menggunakan raw-loader, tetapi karena ini adalah plugin webpack, ini tidak berfungsi di server.

@sukasukaa_

Saya baru saja menulis plugin babel untuk impor penurunan harga. Di ponsel saya sekarang, tetapi jika Anda melihat GitHub saya, Anda akan melihatnya.

@ khrome83 kedengarannya luar biasa. Berharap untuk mencobanya

Terima kasih @ khrome83! Saya akan mencobanya

Saya harus melakukannya dengan sangat cepat, jadi saya tidak memperbarui readme. Tapi Anda hanya memasukkannya sebagai plugin babel, dan kemudian gunakan

impor File dari 'File.md';

Aku berhasil, terima kasih !! Sangat membantu

Ini offtopic tetapi karena masalah ditutup saya merasa bebas untuk menjelaskan :)

Untuk penurunan harga ada 2 hal yang dapat Anda lakukan.

(1)
Salah satunya adalah dengan memasukkan file penurunan harga sebagai string dan kemudian menerjemahkannya ke html / react pada saat runtime. Anda dapat melakukan ini dengan menggunakan loader wrap-in-js babel generik yang mendaftarkannya untuk ekstensi file penurunan harga seperti yang digunakan pada contoh next.js examples/with-globa-stylesheet/.babelrc untuk css.

(2)
Hal lain yang dapat Anda lakukan adalah menerjemahkan penurunan harga pada waktu transpilasi menggunakan markdown-in-js
Ini bisa menjadi lebih menarik dalam beberapa skenario karena dokumen penurunan harga sudah dirender sebelumnya sehingga saat runtime lebih cepat (hanya mengeksekusi js). Selain itu, pustaka memungkinkan Anda menginji komponen React kustom. Sayangnya dalam hal ini Anda harus menulis penurunan harga sebaris di source.js seperti ini .

Jika Anda memilih (2) juga tahu bahwa ada plugin atom yang menyediakan sintaks hilight untuk sintaks markdown-in-js dan itu disebut language-markdown-in-js

@davibe terima kasih atas tipnya! Saya lebih suka markdown diurai sebagai waktu pembuatan, tetapi satu-satunya masalah yang saya miliki dengan markdown-in-js adalah menghindari backticks saat menulis :(. Mungkin saya harus mencoba mengimpor sebagai string menggunakan babel dan kemudian mengumpankannya ke markdown-in-js ?

@sukasukaa_

Ada render penurunan harga nya. Alasan saya menulis plugin saya adalah hal yang sama. Saya menarik markdown sebagai string, lalu saya menjalankannya melalui react-markdown. Ini bekerja semakin baik karena saya bisa meneruskan komponen react untuk mewakili potongan render penurunan harga, seperti komponen List untuk menangani semua daftar. Berfungsi baik dengan JSX Bergaya.

Apakah ada pembaruan tentang ini? Melalui komentar di atas, saya melihat masih belum ada solusi yang tepat saat ini.
@aroda
Apakah mungkin untuk memiliki contoh menggunakan isomorphic-style-loader - https://www.npmjs.com/package/isomorphic-style-loader?

Itu akan sempurna!

Adakah yang punya solusi ketika mengimpor komponen react dari paket npm yang pada gilirannya mengimpor file .css atau .scss? jadi pada dasarnya mentranspilasi file yang diimpor dari node_modules

Saya telah menggunakan Create-React-App (CRA) selama beberapa minggu tetapi hari ini saya menemukan Next.js dan saya sangat bersemangat karena CRA saat ini tidak mendukung rendering sisi server (SSR) yang sangat memalukan.
Saya ingin beralih ke Next.js untuk dukungan SSR-nya di luar kotak tetapi tidak dapat mengimpor file .scss menahan saya.
Adakah yang menemukan cara untuk menambahkan SASS loader ke konfigurasi Webpack?

Setuju dengan cr101, tidak memiliki dukungan untuk CSS / SASS berarti saya harus membuang kerangka css seperti yayasan yang bukan merupakan pilihan bagi saya.

Saya menggunakan repo yang disediakan oleh @davibe tetapi dia tidak lagi memeliharanya, dan build terbaru rusak dengan solusi yang dia miliki .

Akan sangat senang jika seseorang telah menemukan perbaikan untuk ini. Memperbarui ke 2.4.1 mutlak diperlukan karena bug keamanan, jadi saya tidak memiliki opsi untuk mundur.

@Yuripetusko @ cr101 @tgoldenberg Sepenuhnya setuju. Saya pikir sejujurnya selanjutnya sangat luar biasa untuk dapat bekerja di luar kotak. Semuanya baik-baik saja bahkan struktur kode keras (seperti direktori wajib /pages , /static dll.). Tetapi modul scss sama sekali tidak didukung merusak segalanya bagi kami. Kami memiliki struktur scss sangat kompleks dengan breakpoint otomatis dan penghitungan ulang rasio aspek semuanya. Kami bekerja sangat keras untuk membuat struktur kami begitu sempurna. Berikutnya bagus, kita tidak bisa begitu saja membuang semua barang scss yang kita miliki saat ini. Tidak didukung scss adalah satu-satunya tetapi yang paling penting yang menghentikan kita dari migrasi ke alat yang indah ini.

Sebenarnya, # 1615 - ada beberapa tindakan yang sedang terjadi. @timmywil mencoba menyiapkan isomorphic-style-loader untuk bekerja dengan next . Setiap orang yang tertarik dipersilakan untuk bergabung dan berpartisipasi.

Saya mencoba setiap solusi, yang ditunjukkan oleh utas ini, namun dapat membuat salah satu solusi tersebut berfungsi. Jadi saya memutuskan untuk mencoba melakukan upaya saya sendiri dan saya telah mendokumentasikannya di sini

@almeynman terima kasih! pasti akan melihat pendekatan Anda!
Omong-omong, saya telah berhasil membuat modul scss bekerja dengan mengikuti contoh ini . Yang saya lakukan hanyalah menambahkan sass-loader dan mengaktifkan peta sumber.

Saya berhasil membuat next.js suport CSS (bahkan SCSS) dengan cara ini.

Pertama, di next.config.js , sesuaikan konfigurasi webpack dengan menambahkan pemuat yang diberikan dan instance 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;
  }
};

Kemudian, pada kode komponen, membutuhkan file gaya dengan kondisi. Ini memastikan hanya bundling sisi browser yang memiliki modul gaya.

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

Jika Anda tidak keberatan dengan if (process.env.BROWSER) , itu bekerja dengan sempurna.

Pendekatan yang baik ada di sini

@almeynman IMO itu bukan pendekatan yang sangat baik karena Anda memuat kode CSS untuk seluruh situs web di setiap halaman alih-alih hanya memuat gaya CSS yang relevan dengan halaman itu.
Hanya mengimpor file .scss yang Anda perlukan, bukan CSS untuk seluruh situs web, akan sangat mengurangi ukuran halaman dengan hanya memuat kode CSS yang Anda butuhkan.

@ cr101 Hai, saya tidak tahu itu. Saya belum benar-benar menggunakan pengaturan itu, hanya mempostingnya untuk referensi bagi orang lain (saya pikir itu bagus ...). Saya masih menggunakan pendekatan saya yang dijelaskan dalam posting blog . Jika Anda bisa memberi saya umpan balik tentang penyiapan itu akan sangat bagus

Lebih banyak contoh dan diskusi jika ada yang tertarik:

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

Berdasarkan di atas dan utas ini, saya dapat menggunakan PostCSS untuk mengubah:

  • File SCSS global (modulnya sama, Anda hanya perlu titik masuk untuk melakukan pra-kompilasi semua CSS Anda untuk produksi).
  • Pisahkan CSS pihak ketiga dengan font khusus yang direferensikan melalui URL relatif (diselesaikan dengan sihir sebaris).

ke dalam satu file CSS seharga /static/styles/app.css untuk ditayangkan dalam produksi, dengan hot reload masih berfungsi. Perhatikan penggunaan styled-jsx tetapi itu bisa dilakukan tanpa, dengan menggunakan <style dangerouslySetInnerHTML={} />

postcss.config.js

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

next.config.js

Loader untuk mengubah .scss dalam mode dev untuk hot-reload dan mengekstrak ke file .css tunggal dalam prod. Ini memberi saya build/app.css jadi pada pembuatan Produksi, saya menambahkan cp build/app.css static/styles/app.css setelah next build agar tersedia dalam ekspor statis dan disematkan di tajuk khusus seperti yang ditunjukkan di bawah ini.

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')])
    ]
  }),
};

tajuk khusus

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>

Semoga ini membantu. Beri tahu saya jika ada yang membutuhkan klarifikasi lebih lanjut. Menantikan lebih banyak solusi juga. Mudah-mudahan seseorang dapat menghasilkan plugin yang bagus pada akhirnya karena itu masih agak rumit dan integrasi yang berat.

Daripada mengekstrak semua file .scss satu file CSS, akan jauh lebih baik untuk mengkompilasi setiap file .scss diimpor ke dalam file CSS-nya sendiri. Dengan begitu Anda hanya akan memuat gaya CSS yang Anda butuhkan di setiap halaman.
Saya tidak yakin bagaimana Anda akan melakukannya.

Silakan periksa permintaan tarik saya, saya pikir saya punya solusi yang baik:
https://github.com/zeit/next.js/pull/2638

@ crf sebenarnya itu benar. Kami mengimpor perpustakaan UI internal kami sendiri ke dalam berbagai proyek sehingga selalu ada sebagian besar file untuk dimuat (tidak ideal saya tahu, masih mengerjakan modularising binatang itu). Ini akan menjadi langkah selanjutnya dari compile and serve 1 file menjadi X number of files at X locations . Ini menjadi lebih rumit ketika Anda memperhitungkan pengorbanan dari membobol potongan CSS yang lebih kecil vs. versi yang dihosting CDN yang dapat disimpan dan berkinerja eksternal, jadi saya pikir ini akan menyenangkan tetapi melibatkan proyek sendiri. EDIT - pasti jalan keluar dari ruang lingkup untuk apa yang Berikutnya dimaksudkan untuk ditangani, yang terbaik yang harus kita tuju adalah plugin atau pola Berikutnya.

Tidak yakin apakah ini memiliki masalah kinerja, tetapi ini adalah solusi yang cukup sederhana jika Anda menggunakan komponen bergaya atau serupa, cukup buat pembungkus 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>
);

Hal yang saya suka tentang pendekatan ini adalah saya dapat menyesuaikan dari sumber CSS (yang paling sering saya lakukan), tanpa harus menulis timpaan di atas aturan asli jika saya telah mengimpor .css file dari node_modules .

Berikut solusi sederhana untuk mengimpor file CSS menggunakan babel-plugin-inline-import :

.babelrc

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

halaman / komponen

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 ini adalah solusi yang bagus tetapi saya masih mendapatkan kesalahan (saya mengimpor .css build dari https://github.com/Hacker0x01/react-datepicker). Apakah Anda yakin tidak ada hal lain yang sedang dimainkan di sini? Dari error tersebut sepertinya membutuhkan level lain dari pemuatan CSS.

@hilarykitz , @stovmascript solusi bekerja untuk saya, dapatkah Anda mengirimkan kesalahan yang Anda dapatkan?

@stovmascript - bagaimana Anda menghapus cache babel.

  1. Buat file CSS
  2. Impor File
  3. Menerapkan
  4. Ubah file CSS - tambahkan pemilih dan gaya baru
  5. Saksikan bahwa Babel Cache menyimpan versi lama

@ khrome83 Anda harus menghapus node_modules / .cache

Saya menemukan solusi yang lebih baik menggunakan plugin babel-inline-loader yang membersihkan cache dan bekerja dengan cara di atas. Masalah dengan metode itu adalah Anda hanya dapat menerapkan gaya global. Saat digunakan dalam tag non <style jsx global> , itu tidak akan menambahkan data-jsx dengan benar yang mengalahkan tujuan.

Saya menemukan solusi yang lebih baik menggunakan plugin babel-inline-loader yang membersihkan cache dan bekerja dengan cara di atas. Masalah dengan metode itu adalah Anda hanya dapat menerapkan gaya global. Saat menggunakan di non

Saya menambahkan contoh menggunakan solusi @stovmascript :

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

Bagaimana Anda menyertakan lebih dari satu css eksternal?
Saya menggunakan 2 libs yang memerlukannya dalam komponen yang sama, masing-masing bekerja secara terpisah, tetapi saya tidak tahu cara menggabungkannya.

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 coba <style jsx global>{ rtStyle }{dpStyle}</style>

@almeynman mendapatkan ini:

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

@CHarnel coba letakkan keduanya di string template

@CHarnel coba pendekatan ini
<style jsx global>{ $ {rtStyle} $ {dpStyle} }</style>

@jam

saya mencoba untuk meletakkan css tersebut dalam satu file js dan mengekspornya

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

export default bootstrap + styles

dan kemudian adil

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

Dengan https://github.com/sheerun/extracted-loader yang saya buat, Anda dapat menggunakan ExtractTextPlugin untuk pengembangan dan produksi, tidak perlu html berbeda dalam pengembangan atau menyuntikkan css ke js.

@comus Saya menggunakan pendekatan Anda, berfungsi dengan baik, terima kasih.

@sheerun bagus, terima kasih

Saya telah mengirimkan contoh yang lebih komprehensif ke next.js:
https://github.com/zeit/next.js/pull/3451

Ini digunakan untuk bekerja sebelum nextjs v4

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

Apa alasan menggunakan pendekatan ini untuk memuat gaya global jsx? <style jsx global>{ rtStyle }{dpStyle}</style>

Saya telah membuat sendiri solusi berdasarkan emit-files-loader . Jika ada yang tertarik, saya dapat mempostingnya di sini, tetapi ini bergantung pada pengaturan server khusus - pada dasarnya Anda harus dapat melayani satu direktori secara statis dalam .next build dir. Ini mungkin dapat dikonfigurasi tanpa server dengan mengandalkan struktur path /_next/... dari server.

Selain itu Anda dapat menulis import stylesheet from './styles/style.[scss|less|stylus|w/e]'; dan ini akan menjadi jalur publik ke file stylesheet Anda, sehingga Anda dapat memasukkannya ke dalam <link> . Ini termasuk ?[hash] untuk cache permanen dan hot-reload.

@timneutkens Saya pernah melihat yang satu ini, apakah ada perkiraan untuk "segera"? Saya melihat itu sudah di kenari.
Saya hanya membutuhkan solusi segera, menghabiskan 2-3 hari untuk mencarinya, dan berhasil menulis solusi saya sendiri yang pada dasarnya merupakan "perbaikan mudah". Saya bahkan berpikir untuk menggabungkannya dengan extract-text-webpack-plugin sehingga seseorang dapat secara statis bergabung dengan semua file .[css|stylus|less|scss] dan membuat semuanya tersedia sebagai satu sumber daya statis seperti biasanya tanpa file berikutnya.

Masalah utama di balik masalah ini menurut saya adalah bahwa ada banyak "keajaiban" yang terjadi di latar belakang di balik produksi dan pembuatan pengembang, dengan hot reload dan semacamnya ... Seseorang mungkin dapat membaca sumbernya dan melihat bagaimana berbagai hal disatukan , tetapi alangkah baiknya jika seseorang yang membuatnya menulis beberapa dokumen tentang itu, saya pikir lebih banyak orang dapat berkontribusi.

@nikolakanacki very soon 🙏 🤐

bahkan berpikir untuk menggabungkannya dengan ekstrak-teks-webpack-plugin sehingga seseorang dapat secara statis menggabungkan semua file yang terpisah. [css | stylus | less | scss] dan membuat semuanya tersedia sebagai sumber daya statis tunggal seperti biasanya tanpa file berikutnya .

Plugin yang saya tulis untuk v5 berikutnya sudah melakukan ini, mereka akan segera menjadi open source 👍

Mengenai menulis dokumen di internal, kami berencana untuk mendokumentasikan bagaimana semuanya bekerja setelah v5 keluar 🙏

@timneutkens Terima kasih!

@timneutkens terima kasih atas pembaruannya, silakan posting pembaruan di sini ketika benda ini mendarat!

Ada berita tentang ini?

Saya tidak yakin berita lain apa yang Anda harapkan 🤔

Ini dirilis di Next.js v5.
Bahkan di readme https://github.com/zeit/next.js#importing -css - sass - less - stylus-files

Juga, PR yang disebutkan telah digabungkan dan masalah ini ditutup.

cukup buat / static folder di root project, dan letakkan file.css Anda di dalam / static, lalu ke Header html struktur hock.

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

lalu gunakan className di mana saja!

@comus

Jauh lebih komprehensif dan cerdas..terima kasih untuk ini..Saya telah mencari solusi semacam ini sepanjang hari ..

cukup buat / static folder di root project, dan letakkan file.css Anda di dalam / static, lalu ke Header html structure hock.

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

lalu gunakan className di mana saja!

Buat folder 'publik' di root aplikasi Anda (tempat file package.json berada).

Dukungan ditambahkan melalui # 8626!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat