Forked from tompascall's project js-to-styles-var-loader.
Please read from the original project page for the details.
I am currently working on the dev
branch. master
branch is still the original project.
Demos and tests have not been updated to this and are expected to run to errors. I would find another time to update them. Despite the updated loader works in my own project, I don't guarantee that this would work for all cases.
I am using selected components from iView, which less
is used. iView provides a template less
file, with a long list of variables which you can select from to overwrite its default styles.
My project uses Vue.js, and scss
is used in the template file. I would like to have a list of set style variables in scss
.
Meanwhile, in many cases, the JavaScripts inside the Vue components would like to know the styles.
To make the styles consistent across a project, it would be best if the styles where the above-mentioned 3 places wish to reference to are the same. However, it would be rather silly to maintain a less
file, an scss
file and a js
file for almost the same contents.
To solve this problem, the project has the following files:
shared_variables.styles.js
: exports a js Object for styles to be shared across iView and my own stylesiview_overwrite.less
: importsshared_variables.styles.js
, plus some additionalless
variablescommon.styles.js
: importsshared_variables.styles.js
, plus some additional styles in js, and exports a js Object.common.scss
: importscommon.styles.js
, plus some additionalscss
. The additionals would not be available for js.
common.scss
would be injected at the top of the scss
styles in every .vue
Vue template file with sass-resources-loader
.
common.styles.js
can be imported in the main.js
or app.js
of a project and set as global parameter.
-
The original loader "cleverly" detects which processor to use (
less
orsass
) by looking at the file exntensions. However, this would not work when thescss
variables are to be injected into the Vue temple files. To solve the problem, I added auseProcessor
option. -
The RegEx check for
require
function so that webpack alias etc. which usually uses'@'
sign can be supported. Webpackresolve
is now used to resolve the required path in place ofpath.join
. Update: webpack cannot resolve if it is only the filename inside therequire
. It will output anError
. In this case,path.join
would take over. -
As webpack
resolve
, this is now an async loader.
For example, in webpack.config.js
:
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader',
options: {
extractCSS: true,
loaders: {
'css': 'vue-style-loader!css-loader',
'less': 'vue-style-loader!css-loader!less-loader',
'scss': [
'vue-style-loader',
'css-loader',
'postcss-loader',
'sass-loader',
//'js-to-styles-var-loader', <= original loader would not work
{
loader: 'js-to-styles-var-loader',
options: {
useProcessor: 'scss', // specify it is 'sass', 'scss' or 'less'
}
},
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, 'my_directory_to_styles/common.scss'),
},
},
],
// ...
}
}
]
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'sass-loader',
options: {
importer: sassJsonImporter,
}
},
{
loader: 'js-to-styles-var-loader',
options: {
useProcessor: 'scss',
}
},
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, 'my_directory_to_styles/common.scss'),
}
}
]
}
In common.styles.js
:
var shared_vars = require('./shared_variables.styles.js'); // This is a Node require
In iview_overwrite.less
:
@import "~iview/src/styles/index.less"; /* This is the less @import */
require('shared_variables.styles.js'); /* This is for the loader to parse */
In common.scss
:
require('common.styles.js'); /* This is for the loader to parse */