Reputation: 10667
I have a package and i want export my SASS variables to other packages use it. Currently my all .scss files are compiles and put in /dist/main.css file. My webpack config:
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: ['./src/index.js'],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel'
},
{
test: /\.(scss|sass|css)$/,
loader: ExtractTextPlugin.extract("style", "css!sass")
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=10000&name=fonts/[hash].[ext]'
},
{
test: /\.scss$/, loader: 'style!css!sass!sass-resources'
}
]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
output: {
path: __dirname + '/build',
publicPath: '/',
filename: 'index.js',
library: 'Supernova',
libraryTarget: 'umd'
},
externals: {
'react': 'react',
'react-dom': 'react-dom'
},
plugins: [
new ExtractTextPlugin("[name].css")
]
};
My objective is create a package like bootstrap-sass.
Upvotes: 4
Views: 6879
Reputation: 5154
If you want to make the variables you use within your sass files available to consumers of your published package, then you'll need to look at some special configuration for node-sass.
Currently (and as of the time you posted this) node-sass supports writing your own custom sass functions in javascript: https://github.com/sass/node-sass#functions--v300---experimental
This is untested, but we did this a while ago at a company i worked for...to do what you want, you'd need something like:
src/
your-package.js
your-styles.scss
tools/
constants/
colours.js
webpack/
...
base.sass.js
base.js
development.js
production.js
sass/
functions/
colours.js
# tools/webpack/base.sass.js
const Config = require('webpack-config').default
import {
signature as ColourSignature,
handler as ColourHandler
} from '@tools/sass/functions/colours
module.exports = new Config()
.merge({
module: {
rules: [
{
test: /\.scss$/,
use: [
...
{ loader: 'sass-loader',
options: {
sourceMap: true,
functions: {
[ColourSignature]: ColourHandler
}
}
},
]
}
]
}
})
# src/your-package.js
import Colours from '@tools/constants/colours'
import "./your-styles.scss"
export default YourAwesomeComponent {
static Colours = Colours
}
export const colours = Colours
# src/your-styles.scss
.your-awesome-component {
background-color: ColourGet(veganvomit, sobrightithurts);
}
# tools/sass/functions/colour.js
import Colours from '@tools/constants/colours'
export signature = 'ColourGet($name, $shade: default)'
export handler = function(name, shade) {
const colour = Colours[name]
if (!colour) return
if (typeof colour === 'string') return colour
return colour[shade]
}
# tools/sass/constants/colours.js
export default {
veganvomit: {
sobrightithurts: "darkkhaki",
light: "#D2691E",
default: "#8B4513",
somethingsomethingsomethingdarkside: "#000"
}
}
So now when you publish your package, they can access sass variables from your default export YourAwesomeClass.Colours
or they can import it directly `import { Colours } from 'your-awesome-package'
Upvotes: 2
Reputation: 134
I highly recommend using webpack-merge
to separate out your Sass config to make it easy for other packages to use it. For your current config, I would do three things:
webpack-merge
to your project (npm i --save-dev webpack-merge
).Put your Sass config into a separate file, named something like webpack.sass-config.js
. Have it include the following:
var ExtractTextPlugin = require('extract-text-webpack-plugin');
exports.config = function(options) {
return {
module: {
loaders: [
{
test: /\.(scss|sass|css)$/,
loader: ExtractTextPlugin.extract("style", "css!sass")
},
{
test: /\.scss$/, loader: 'style!css!sass!sass-resources'
}
]
},
plugins: [
new ExtractTextPlugin("[name].css")
]
}
}
// Side note: returning a function instead of a plain object lets
// you pass optional parameters from your main config file. This
// is useful if you want to make something like your compiled css
// file name different for another Webpack project without having
// to edit your Sass configuration file.
Update your webpack.config.js
to the following:
var merge = require('webpack-merge');
// import your separated Sass configuration
var sassConfig = require('webpack.sass-config');
// Define your common config for entry, output, JSX, fonts, etc.
var common = {
entry: ['./src/index.js'],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel'
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=10000&name=fonts/[hash].[ext]'
}
]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
output: {
path: __dirname + '/build',
publicPath: '/',
filename: 'index.js',
library: 'Supernova',
libraryTarget: 'umd'
},
externals: {
'react': 'react',
'react-dom': 'react-dom'
}
};
// Merge your common config and Sass config
var config = merge(
common,
sassConfig.config()
);
// Export the merged configuration
modules.exports = config;
Obviously, this can go far beyond just your Sass config. I use webpack-merge
to separate my development config from my production config. This article on Survive JS is a great resource for how to make the most of your Webpack setup.
Upvotes: 0