├── .gitignore ├── LICENSE ├── README.md ├── index.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # misc 9 | .DS_Store 10 | /.vscode 11 | /.devcontainer 12 | 13 | # debug 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | 18 | # env files 19 | .env 20 | .env.local 21 | .env.development.local 22 | .env.test.local 23 | .env.production.local 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Vladimir Alexandrov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Next.js + Linaria 2 | 3 | Adds [Linaria](https://github.com/callstack/linaria) to [built-in CSS support](https://nextjs.org/docs/basic-features/built-in-css-support) in Next.js. 4 | 5 | > The version `1.0.0` and above only works with linaria@3. If you need support for linaria@2, please use version `0.11.0` of this package. 6 | 7 | > The version `0.11.0` of this package requires next@9.5.4 or above. 8 | 9 | > For next@9.2.0-9.5.3 use version `0.10.0` of this package. 10 | 11 | This module is intended to be used with Next.js built-in CSS support (https://nextjs.org/docs/basic-features/built-in-css-support) and probably will not work with custom CSS handling. 12 | 13 | ## Installation 14 | 15 | ``` 16 | npm install --save next-linaria linaria 17 | ``` 18 | 19 | or 20 | 21 | ``` 22 | yarn add next-linaria linaria 23 | ``` 24 | 25 | ## Usage 26 | 27 | Create a `next.config.js` in your project 28 | 29 | ```js 30 | // next.config.js 31 | const withLinaria = require('next-linaria'); 32 | module.exports = withLinaria({ 33 | /* config options here */ 34 | }); 35 | ``` 36 | 37 | ### Linaria options 38 | 39 | ```js 40 | // next.config.js 41 | const withLinaria = require('next-linaria'); 42 | module.exports = withLinaria({ 43 | linaria: { 44 | /* linaria options here */ 45 | }, 46 | }); 47 | ``` 48 | 49 | ### Configuring Next.js 50 | 51 | Optionally you can add your custom Next.js configuration as parameter 52 | 53 | ```js 54 | // next.config.js 55 | const withLinaria = require('next-linaria'); 56 | module.exports = withLinaria({ 57 | webpack(config, options) { 58 | return config; 59 | }, 60 | }); 61 | ``` 62 | 63 | ## License 64 | 65 | The MIT License (MIT) 66 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const LINARIA_EXTENSION = '.linaria.module.css'; 2 | 3 | function traverse(rules) { 4 | for (let rule of rules) { 5 | if (typeof rule.loader === 'string' && rule.loader.includes('css-loader')) { 6 | if ( 7 | rule.options && 8 | rule.options.modules && 9 | typeof rule.options.modules.getLocalIdent === 'function' 10 | ) { 11 | let nextGetLocalIdent = rule.options.modules.getLocalIdent; 12 | rule.options.modules.mode = 'local'; 13 | rule.options.modules.auto = true; 14 | rule.options.modules.exportGlobals = true; 15 | rule.options.modules.exportOnlyLocals = false; 16 | rule.options.modules.getLocalIdent = (context, _, exportName, options) => { 17 | if (context.resourcePath.includes(LINARIA_EXTENSION)) { 18 | return exportName; 19 | } 20 | return nextGetLocalIdent(context, _, exportName, options); 21 | }; 22 | } 23 | } 24 | if (typeof rule.use === 'object') { 25 | traverse(Array.isArray(rule.use) ? rule.use : [rule.use]); 26 | } 27 | if (Array.isArray(rule.oneOf)) { 28 | traverse(rule.oneOf); 29 | } 30 | } 31 | } 32 | 33 | module.exports = (nextConfig = {}) => { 34 | return { 35 | ...nextConfig, 36 | webpack(config, options) { 37 | traverse(config.module.rules); 38 | config.module.rules.push({ 39 | test: /\.(tsx|ts|js|mjs|jsx)$/, 40 | exclude: /node_modules/, 41 | use: [ 42 | { 43 | loader: require.resolve('@linaria/webpack-loader'), 44 | options: { 45 | sourceMap: process.env.NODE_ENV !== 'production', 46 | ...(nextConfig.linaria || {}), 47 | extension: LINARIA_EXTENSION, 48 | }, 49 | }, 50 | ], 51 | }); 52 | 53 | if (typeof nextConfig.webpack === 'function') { 54 | return nextConfig.webpack(config, options); 55 | } 56 | return config; 57 | }, 58 | }; 59 | }; 60 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-linaria", 3 | "version": "1.0.1-beta", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-linaria", 3 | "version": "1.0.1-beta", 4 | "description": "Linaria support for Next.js applications", 5 | "main": "index.js", 6 | "dependencies": {}, 7 | "devDependencies": {}, 8 | "peerDependencies": { 9 | "@linaria/webpack-loader": "*" 10 | }, 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/Mistereo/next-linaria.git" 17 | }, 18 | "keywords": [ 19 | "linaria", 20 | "next", 21 | "next.js", 22 | "css" 23 | ], 24 | "author": "Vladimir Alexandrov", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/Mistereo/next-linaria/issues" 28 | }, 29 | "homepage": "https://github.com/Mistereo/next-linaria#readme" 30 | } 31 | --------------------------------------------------------------------------------