Ini adalah masalah yang berlebihan yang saya tahu, tetapi saya membuka masalah ini dengan sengaja. Sudah tiga hari saya menyiapkan boilerplate next.js (dengan redux, redux-saga, ...) dan dua hari saya terjebak dalam menyiapkan memuat file css dan scss eksternal. Saya telah memeriksa contoh with-global-stylesheet dan with-scoped-stylesheet-and-postcss , tetapi masing-masing dari mereka memiliki masalah besar yang disebutkan dalam masalah sebelumnya. Saya telah melihat terlalu banyak masalah terbuka dan tertutup yang memecahkan masalah ini dengan peretasan... Saya pikir itu ide yang baik bahwa alih-alih meninggalkan masalah untuk menemukan solusi terbaik, selesaikan dengan solusi yang tersedia saat ini sampai menemukan yang lebih baik. Karena banyak yang memiliki masalah ini sekarang dan ingin melihatnya diselesaikan sekarang!
Saya setuju, hanya styled-jsx yang memiliki dukungan clean (termasuk hot reloading) dan itulah yang mencegah saya menggunakan Next.js untuk apa pun kecuali ketika saya membutuhkan prototyping cepat.
Saya pikir solusi untuk masalah pelingkupan CSS dari Modul CSS jauh lebih bersih, ditambah dengan Modul CSS itu masih mungkin untuk meneruskan kelas ke komponen anak (coba letakkan kelas non-global pada SVG yang diimpor dengan babel-plugin-inline-react-svg
dengan styled-jsx).
Itu dan saya lebih suka memiliki file .css
untuk mencegah penguncian kerangka kerja sebanyak mungkin dan file CSS eksternal dalam produksi untuk caching (dan untuk membuat polyfill MQ seperti Respond.js berfungsi jika Anda kurang beruntung untuk masih harus mendukung IE8).
+1 besar-besaran
Ini adalah frustrasi besar bahwa hal sederhana seperti css/scss eksternal hampir tidak mungkin dicapai dengan next.js, yang menjadikannya tidak berguna untuk 90% aplikasi saya.
Saya bekerja dengan bootstrap, dan saya memerlukan konfigurasi di mana akan ada satu impor bootstrap css global, dengan tambahan css lingkup eksternal.
Sementara kami berhasil mendapatkan stylus eksternal yang berfungsi dengan jsx 1 ( webpack untuk menangani kompilasi ), mengalami kesulitan mencari tahu di jsx 2 yang ditata sejak melanggar perubahan penanganan file css terpisah yang diperkenalkan.
Pendekatan saat ini:
import ComponentStyles from './footer.styl';
...
<style jsx>
{ComponentStyles}
</style>
Akan sangat bagus untuk melihat https://github.com/zeit/next.js/tree/master/examples/with-styled-jsx-scss bekerja dengan file scss eksternal.
Kami mengalami cobaan yang sama saat menyiapkan lingkungan.
Akhirnya kami menyelesaikan dengan stylesheet global dengan scss+post css dengan lost-grid.
Reload panas berfungsi, jadi meskipun ini bukan solusi ideal (karena stylesheet global dimuat sekaligus), ini adalah kompromi yang baik.
Ketergantungan
"autoprefixer": "^7.1.6",
"babel-plugin-module-resolver": "^2.7.1",
"babel-plugin-wrap-in-js": "^1.1.1",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"pixrem": "^4.0.1",
"postcss-easy-import": "^3.0.0",
"postcss-loader": "^2.0.8"
Di package.json
...
"postcss": {
"plugins": {
"lost": {},
"postcss-easy-import": {
"prefix": "_"
},
"autoprefixer": {},
"pixrem": {}
}
}
...
Di next.config.js
webpack: (config, { dev }) => {
config.module.rules.push(
{
test: /\.(css|scss)/,
loader: 'emit-file-loader',
options: {
name: 'dist/[path][name].[ext]'
}
}
,
{
test: /\.css$/,
use: ['babel-loader', 'raw-loader', 'postcss-loader']
}
,
{
test: /\.s(a|c)ss$/,
use: ['babel-loader', 'raw-loader', 'postcss-loader',
{ loader: 'sass-loader',
options: {
includePaths: ['styles', 'node_modules']
.map((d) => path.join(__dirname, d))
.map((g) => glob.sync(g))
.reduce((a, c) => a.concat(c), [])
}
}
]
}
)
return config
}
Di pages/_document.js
...
import stylesheet from 'styles/main.scss'
...
<Head>
<style dangerouslySetInnerHTML={{ __html: stylesheet }} />
</Head>
...
Dan Anda kemudian dapat mengatur gaya Anda mulai dari /styles/main.scss
Semoga membantu
Masalah saya dengan masing-masing dari dua contoh gaya ini ( with-global-stylesheet dan with-scoped-stylesheets-and-postcss ) adalah tidak satupun dari mereka yang mudah diintegrasikan dengan pengujian Jest dan Snapshot dengan CSS di snapshot. Ada orang yang berhasil membuat Jest bekerja dengan Webpack, tapi itu dengan melewatkan CSS secara khusus.
Menjalankan file praprosesor babel-jest
seperti yang dijelaskan dalam jawaban SO ini sepertinya merupakan peretasan yang buruk.
Tampaknya untuk mendapatkan CSS eksternal karena dengan-global-stylesheet Anda harus menggunakan Webpack, tetapi untuk menggunakan Jest Anda tidak dapat mengandalkan Webpack, hanya Babel.
Apakah ada yang punya ide di ruang ini?
Saya menghadapi masalah serupa. Saya baru mengenal nextjs dan saya tidak dapat membuat contoh "with-external-scoped-css" berfungsi dengan baik. Terkadang, css saya dimuat dan terkadang tidak. Saya tidak tahu apakah itu masalah yang sama yang Anda bicarakan.
Menyelesaikan masalah gaya eksternal dengan pemuat ini https://github.com/coox/styled-jsx-css-loader
@ilionic Saya telah memeriksa solusi Anda. Itu bagus! Terima kasih :)
@arefaslani Saya rasa masalah ini belum selesai.
Pada HTTP v1 itu masih merupakan pajak kinerja yang mengerikan untuk memuat banyak CSS, ini meningkatkan waktu untuk menggambar pertama secara dramatis.
Dukungan gaya eksternal yang tepat akan memungkinkan untuk mengimpor CSS dan menghasilkan a bukan sebaris ...
Also, this suggestion doesn't resolve use cases where a CSS framework like bootstrap needs to be included from node_modules. Including Bootstrap as an inline CSS on every page would be horrible. And would negate the benefits of browser caching, e.t.c
In short, I really don't think this issue can be closed... It's still very much an ongoing problem.
@israelidanny Saya tahu apa yang Anda maksud tentang bootstrap, ini bukan solusi peluru perak. Kami mengekstrak bagian inti kerangka bootstrap untuk memisahkan file css sehingga browser dapat menyimpannya di cache. Tidak ideal, tetapi kecanggungan berurusan dengan praprosesor dan kerangka kerja CSS mendorong ke arah pendekatan css-in-js yang lebih baru dan memotong ketergantungan pada kerangka kerja CSS.
@ilionic Saya mengerti apa yang Anda katakan, tetapi tetap saja - memiliki banyak CSS sebaris buruk untuk kinerja (khususnya waktu untuk bingkai pertama). Saya memiliki beberapa proyek di mana kami sangat mengoptimalkan untuk itu.
Sayang sekali kehilangan semua itu, terutama mengingat fakta bahwa kita dapat memiliki DOM yang dirender oleh server.
Mungkin menutup masalah ini, tetapi membuka yang baru, khusus untuk solusi yang memungkinkan kami menautkan CSS eksternal?
Akan aneh untuk mengabaikan praktik pembangunan yang jelas lazim.
@israelidanny setuju, kami masih berjuang dengan kinerja CSS dan tanpa penulisan ulang besar tidak jelas bagaimana menyelesaikannya sehingga memang masalah ini semakin dalam. Mungkin styled-jsx adalah repo yang lebih relevan dalam kasus ini?
@ilionic hmm, saya tidak melihat bagaimana gaya repo jsx akan menjadi tempat yang tepat.
Masalahnya bukan pada mereka, masalahnya adalah mengaktifkan dukungan next.js dari file css eksternal, yang mungkin atau mungkin tidak ada hubungannya dengan styled-jsx.
Bagaimana menurutmu?
@israelidanny Itu bukan solusi terbaik, tapi tetap berhasil. Tapi Anda benar. Memiliki semua inline css di setiap halaman tanpa caching bukanlah solusi terbaik. Saya juga setuju dengan Anda di bagian ini:
Masalahnya bukan pada mereka, masalahnya adalah mengaktifkan dukungan next.js dari file css eksternal, yang mungkin atau mungkin tidak ada hubungannya dengan styled-jsx.
dan sangat tidak setuju dengan @ilionic di:
Mungkin styled-jsx adalah repo yang lebih relevan dalam kasus ini
Saya mengelola solusi dengan styled-jsx/css loader . Anda dapat melihat kode dari https://github.com/P233/nextjs-with-scss
Namun, saya perhatikan file @import
ed scss tidak ditonton dan tidak akan memicu hot reload, yang benar-benar membuat saya frustrasi.
Saya telah membuat https://github.com/sheerun/extracted-loader untuk memuat ulang file stylesheet yang diekstraksi. Ini bekerja cukup bagus bahkan untuk pengembangan, jadi dangerouslySetInnerHTML
tidak diperlukan.
Anda menggunakannya sebagai berikut:
config.module.rules.push({
test: /\.css$/,
use: ['extracted-loader'].concat(ExtractTextPlugin.extract({
/* Your configuration here */
}))
})
config.plugins.push(new ExtractTextPlugin('index.css'))
@sheerun , terima kasih, tapi bagaimana saya menyuntikkan css saya ke dalam komponen?
Anda tidak menyuntikkan, Anda mengekstrak semuanya dengan ExtractTextPlugin dan menulis yang berikut:
<Head>
<link rel='stylesheet' type='text/css' href="/static/index.css" />
</Head>
di komponen Anda sesuatu seperti
import './styles.scss'
Seharusnya cukup
ok, tapi sekarang saya memiliki kesalahan:
./components/Home/Home.js
Modul tidak ditemukan: Kesalahan: Tidak dapat menyelesaikan 'css-loader' di 'D:\Sites\work\VisualProposal'
@ ./components/Home/Home.js 13:0-22
@ ./halaman?entri
@ multi ./halaman?entri
komponen Home.js saya:
import { observer } from 'mobx-react';
import './Home.scss'
import MainSection from './MainSection/MainSection'
import Sections from './Sections/Sections';
import Features from './Features/Features'
import Pricing from './Pricing/Pricing';
import Footer from './Footer/Footer'
const Home = () => {
return (
<div className="Home">
<MainSection/>
<Sections/>
<Features/>
<Pricing/>
<Footer/>
</div>
)
};
export default observer ( Home );
next.config.js saya:
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
webpack: function ( config, { dev } ) {
config.module.rules.push({
test: /\.(sa|sc|c)ss$/,
use: ['extracted-loader'].concat(ExtractTextPlugin.extract({
use: [
"babel-loader",
{
loader: 'css-loader',
options: {
url: true,
minimize: !dev,
sourceMap: dev,
importLoaders: 2
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: dev,
plugins: [
require('autoprefixer')({
/* options */
})
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: dev
}
}
]
}))
});
config.plugins.push(new ExtractTextPlugin('index.css'));
if ( config.resolve.alias ) {
delete config.resolve.alias['react'];
delete config.resolve.alias['react-dom']
}
for (let index = 0; index < config.plugins.length; index += 1) {
if (config.plugins[index].constructor.name === "UglifyJsPlugin") {
config.plugins.splice(index, 1, new UglifyJSPlugin({
sourceMap: true,
parallel: true,
}));
break;
}
}
return config
}
};
Jadi apa yang saya lakukan salah?
Saya telah menambahkan contoh yang cukup canggih dengan SCSS, url() di stylesheet, img[src]. Ini harus bekerja dari kotak dengan now.sh dan memiliki hot-reload dan mengekspor dikonfigurasi dengan benar:
https://github.com/sheerun/extracted-loader/tree/master/examples/with-next
@psycura Saya melihat Anda menggunakan Windows sehingga mungkin tidak langsung bekerja untuk Anda, tetapi tolong kirim perbaikan PR
malu untuk Nextjs yang tidak memungkinkan untuk bekerja dengan file css eksternal. Ada banyak sekali paket siap pakai dengan stylsheetnya sendiri yang ingin saya gunakan dalam proyek saya. Tapi aku tidak bisa! Saya mencoba beberapa opsi tetapi tidak ada yang benar-benar berfungsi: sudah menghabiskan satu hari untuk ini.
@mkozhukharenko Ini bekerja dengan file css dan scss. Saya akan menambahkan contoh dengan https://github.com/coox/styled-jsx-css-loader . Ini memuat css eksternal sebagai scoped atau global styled-jsx. Untuk scss global umum, saya sarankan menggunakan node-sass dan postcss.
@arefaslani Saya mencoba semua opsi, tidak ada yang berhasil untuk saya. Saya benar-benar kecewa dengan kerangka kerja ini. Bagaimana mungkin tugas yang begitu mudah bisa menjadi sulit? Saya tidak akan menggunakan kerangka kerja kerangka berpendirian seperti itu lagi.
@mkozhukharenko Lihat contoh ini: https://github.com/arefaslani/next.js/tree/canary/examples/with-external-scoped-scss. Saya membuat permintaan tarik untuk menambahkannya ke contoh repo utama.
coba tambahkan lebih banyak css ke file Anda dan Anda akan melihat bahwa styled-jsx
tidak dapat mengatasinya. Saya mendapatkan 'jsx-undefind' tidak dapat ditemukan atau 'jsx-4231512' tidak dapat ditemukan kesalahan
@arefaslani Apakah ada cara untuk menggunakan pola ini dengan contoh Anda?
import classes from './styles.scss'
const MyComponent = () => (
<header className={classes.header}>Hello</header>
)
@protoEvangelion Sayangnya, saat ini hanya berfungsi dengan styled-jsx.
owh ok makasih atas fast respon nya :)
Sayang sekali bahwa build next.js tidak berpikir untuk menggunakan kembali sumber daya yang ada pada awalnya. Buang-buang waktu menyiapkan aturan kompleks hanya untuk file css.
Saya sedang mengerjakan solusi untuk masalah ini yang memungkinkan semua pemuat webpack berfungsi.
Saya juga ingin menunjukkan bahwa saya pribadi tidak menyukai nada bicara orang dalam masalah ini.
Saya benar-benar mengerti Anda ingin mengimpor css. Dan kami sangat menyadari permintaan ini. Itu sebabnya saya menghabiskan seminggu terakhir untuk mencari solusi terbaik 👍
Lebih lanjut tentang ini segera. Sampai saat itu, harap bersikap baik dan selamat berlibur
Hai, semuanya, saya menemukan solusi di github lain,
Gunakan skeleton-loader untuk mengikuti aturan BEM untuk mencapai efek yang sama seperti css-modul,
Karena Anda perlu membuat .scss.json, dan kemudian menggunakan sampah untuk menghapus .scss.json yang dihasilkan. Meskipun rasanya tidak ideal, saya ingin mengirim Anda untuk melihat apakah ada metode lain yang lebih baik.
Hi, everybody, I found a solution on another github,
Use skeleton-loader to comply with BEM rules to achieve the same effect as css-modules,
Because it will need to generate. Scss.json, then use the trash will be generated. Scss.json delete
Although it feels less than ideal, give it to you to see if there are any other better ways
@timneutkens Bagaimana dengan solusi Anda?
Saya telah membuat boilerplate Berikutnya yang mendukung impor scss, css, dan banyak lagi fitur lainnya. Lihatlah dan jika Anda menyukainya, beri bintang;)
https://arefaslani.github.io/next-boilerplate
@Bobeta Saya sudah berhasil, ada beberapa kasus tepi yang ingin saya perbaiki sebelum mengirimkan PR.
@timneutkens Senang mendengarnya! Kapan Anda mengharapkannya untuk diterbitkan?
@Bobeta Saya yakin dia akan memposting di utas ini ketika sudah diterbitkan dan siap untuk kita gunakan.
@jthegedus Saya yakin dia juga akan melakukannya, tetapi saya bertanya-tanya tentang perkiraan sehingga orang dapat mendasarkan keputusan pada @timneutkens itu
Komentar yang paling membantu
Saya juga ingin menunjukkan bahwa saya pribadi tidak menyukai nada bicara orang dalam masalah ini.
Saya benar-benar mengerti Anda ingin mengimpor css. Dan kami sangat menyadari permintaan ini. Itu sebabnya saya menghabiskan seminggu terakhir untuk mencari solusi terbaik 👍
Lebih lanjut tentang ini segera. Sampai saat itu, harap bersikap baik dan selamat berlibur