I'm trying to use Foundation with Webpack 2 using the sass-loader.
I'm importing Foundation with
#import 'foundation-sites/scss/foundation';
And get an import error as it can't find foundation. Reading the docs for sass-loader suggests that I should actually use:
#import '~foundation-sites/scss/foundation';
Which fixes the import error but creates a new problem.
The error I receive is
ModuleBuildError in
Module build failed:
#import "normalize";
^
File to import not found or unreadable: normalize
File to import not found or unreadable: normalize
Parent style sheet: ... /node_modules/foundation-sites/scss/foundation.scss
in ... /node_modules/foundation-sites/scss/foundation.scss (line 9, column 1)
In my webpack config file I'm also using the ExtractTextPlugin as below:
module: {
rules: [
{
test: /\.(scss|css)$/,
loader: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: [
{
loader: 'css-loader'
},
{
loader: 'sass-loader',
query: {
includePaths: [path.resolve(__dirname, "./node_modules")]
}
}
]
})
}
]
},
resolve: {
modules: ['node_modules']
}
I believe this comes from the webpack isn't resolving to the node_modules folder for some reason but unsure where the cause comes from.
Try this, as that the only thing that worked for me.
new webpack.LoaderOptionsPlugin({
options: {
context: '/', // <- putting this line right under "options" did the trick
sassLoader: {
includePaths: [
path.resolve(__dirname, 'vendor/zurb/foundation/scss'),
]
}
}
})
Related
The symptom
When are run rollup -c I get a reasonable build, but I get this error if I use the SCSS double slash comments:
CssSyntaxError: //../packages/core/src/styles/layout.module.scss:56:8: Unknown word
You tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser
As far as I can tell, I have setup the plugin to use sass and to use CSS Modules. When I try to set the parser to "postcss-scss" I get this other error:
[!] (plugin postcss) TypeError: node.getIterator is not a function
rollup.config.js
import url from "#rollup/plugin-url";
import svgr from "#svgr/rollup";
import autoprefixer from "autoprefixer";
import { resolve } from "path";
import postcssNormalize from "postcss-normalize";
import babel from "rollup-plugin-babel";
import peerDepsExternal from "rollup-plugin-peer-deps-external";
import postcss from "rollup-plugin-postcss";
import { nodeResolve } from "#rollup/plugin-node-resolve";
import commonjs from "#rollup/plugin-commonjs";
import typescript from "#rollup/plugin-typescript";
import packageJson from "./package.json";
export default [
{
input: "src/components/index.ts",
output: [
{
file: `${packageJson.main}`,
format: "cjs",
sourcemap: true,
},
{
file: `${packageJson.module}`,
format: "esm",
sourcemap: true,
},
],
plugins: [
// include peer deps in the package
peerDepsExternal(),
// The next 2 allow importing commonjs packages like classnames
commonjs(),
nodeResolve(),
// transform
babel({
exclude: "node_modules/**",
}),
typescript({
typescript: require("typescript"),
tsconfig: "./tsconfig-prod.json",
}),
postcss({
plugins: [autoprefixer(), postcssNormalize()],
// exclude: "src/styles/**/*.scss",
namedExports: true,
sourceMap: true,
extract: false,
// modules: true,
autoModules: true,
minimize: true,
extensions: [".scss"],
use: ["sass"],
// parser: "postcss-scss",
}),
url(),
svgr(),
],
},
};
There are a couple of commented out options, which I have also tried. Yes, I can switch comment type - the sheer number of files notwithstanding, but it bothers me that this setup is not quite working, so any help would be much appreciated.
In the src/components folders I have this folder strcuture pattern for each component:
components ->
> Button ->
> index.ts
> Button.tsx
> Button.module.scss
I have a simple rollup project that has the following structure
src
index.mjs
style.sass
package.json
rollup.config.mjs
In my rollup file I create the plugin like this...
const pcss = postcss({
preprocessor: (content, id) => new Promise((resolve, reject) => {
const result = sass.renderSync({
file: id,
includePaths: ["src", "node_modules"]
})
resolve({ code: result.css.toString() })
}),
plugins: [
autoprefixer
],
extensions: ['.sass', '.scss']
})
Then I have the simple import in my sass file like this...
#import "#material/button/mdc-button";
But when I run this I get...
Error: File to import not found or unreadable: #material/button/mdc-button.
at options.error (/Users/jackiegleason/Code/jrg-material/packages/components/node_modules/node-sass/lib/index.js:291:26)
If I change to
#import "~#material/button/mdc-button";
I get a little closer with...
Error: File to import not found or unreadable: #material/elevation/mixins.
How do I get it to recognize the files without an extension so the other imports work?
I got it to work like this...
const pcss = postcss({
modules: true,
extensions: ['.sass', '.scss'],
namedExports: true,
plugins: [
autoprefixer
],
use: [
[
'sass', {
includePaths: [path.resolve('node_modules')]
}
]
]
})
I'm struggling to implement material-components-web in a React application properly with Webpack 2. I want to import the Sass files so they can be themed.
Here's what I think are relevant parts of my config:
var webpackConfig = module.exports = {
context: path.resolve(__dirname, '..'),
entry: {
'main': [
'./src/theme/main.scss',
'./src/client.js'
]
},
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'style-loader',
}, {
loader: 'css-loader',
options: {
modules: true,
importLoaders: 3,
sourceMap: true,
localIdentName: '[local]___[hash:base64:5]'
}
}, {
loader: 'autoprefixer-loader',
options: {
browsers: 'last 2 version'
}
}, {
loader: 'resolve-url-loader',
}, {
loader: 'sass-loader', // compiles Sass to CSS
options: {
outputStyle: 'expanded',
sourceMap: true,
includePaths: ['../src', '../node_modules', '../node_modules/#material/*']
.map(d => path.join(__dirname, d))
.map(g => glob.sync(g))
.reduce((a, c) => a.concat(c), [])
}
},
],
}
]
},
resolve: {
modules: [
'src',
'node_modules'
],
extensions: ['.json', '.js', '.jsx', '.scss']
}
};
and I start my main.scss with this:
$mdc-theme-primary: #4a90e2;
$mdc-theme-accent: #f22745;
$mdc-theme-background: #fff;
#import '~material-components-web/material-components-web.scss';
All my app Sass files load fine, but the material-components-web import doesn't seem to work at all but also doesn't throw any errors.
If I add 'material-components-web/dist/material-components-web.min.css' to entry.main then it works but then I'm obviously unable to change the theme as easily so that seems wrong. What should I do here?
Please check the latest documentation about importing the default theme here: https://github.com/material-components/material-components-web/blob/master/docs/theming.md#step-3-changing-the-theme-with-sass
I followed 100% and it works for me using React to, according to this you probably want to change the line
#import '~material-components-web/material-components-web.scss';
to
#import "material-components-web/material-components-web";
and webpack 2 should be able to handle it.
Let us know if you found a solution.
I was using D3 v3 with webpack which was simple with one single package. Now that D3 v4 has become modular with separate packages, I am unable to bundle them into single package.
I have referred to mbostock's article below using rollup but it fails saying it is unable to load d3 from index.js. Can anyone help me with how to bundle them using webpack?
EDIT 1:
I removed d3 from the rollup options and the rollup worked fine. I have explained the steps below
D3 v4 installed.
Added rollup config and storing to ./dist/d3.min.js
pointed webpack to the ./dist/d3.min.js
tried resolve.alias in webpack and require("d3") in one home.js. But no luck it says
cannot resolve module d3 in home.js
tried webpack.Provideplugin in home.js. Still the above error.
Can anyone please help me with getting this d3 loaded?
Rollup.js
import node from "rollup-plugin-node-resolve";
export default {
entry: "index.js",
format: "umd",
moduleName: "d3",
plugins: [node()],
dest: "./dist/d3.js"
};
index.js
export * from "d3-selection";
export * from "d3-zoom";
export * from "d3-scale";
export * from "d3-drag";
export * from "d3-force";
export * from "d3-axis";
webpack.config.js
var webpack = require('webpack')
var path = require('path')
module.exports = {
entry: [
//"./dist/d3-combined.js",
"./client/home.js"
,"./client/pages.js"
,"./client/graph.js"
,"./client/orient_databases.js"
,"./node_modules/d3/d3.js",
,"./public/jquery-2.2.4.min.js"
]
,output: {
path: path.join(__dirname,'dist')
// ,path: '/static'
,publicPath: 'http://localhost:3000/scripts/'
,filename: 'bundle.js'
}
,plugins :[
new webpack.ProvidePlugin({
jquery : "jquery"
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]
,module: {
// avoid webpack trying to shim process
noParse: /es6-promise\.js$/,
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
// excluding some local linked packages.
// for normal use cases only node_modules is needed.
exclude: /node_modules|vue\/dist|vue-router\/|vue-loader\/|vue-hot-reload-api\//,
loader: 'babel-loader',
query : {
presets : ['es2015']
//,optional : ["runtime"]
}
}
]
}
,resolve : {
//root : [path.resolve('./node_modules')],
alias : [ {"d3": path.join(__dirname,"dist/d3.min.js") } ],
modulesDirectories : ["node_modules"]
}
}
There are quite a few incompatibilities with D3 v4's rollup approach and webpack—yours is totally a sensible approach.
It looks like you're missing the minification step? (Rollup.js creates d3.js, but webpack.config.js expects d3.min.js)
It's also possible that webpack v2's new configuration has some relevant fixes.
This setup works for me (using webpack v2):
home.js
let d3 = require('d3');
rollup.config.js
import npm from 'rollup-plugin-node-resolve';
export default {
entry: './d3.bundle.js',
format: 'umd',
moduleName: 'd3',
plugins: [npm({jsnext: true})],
dest: './dist/d3.js'
};
d3.bundle.js
export * from "d3-selection";
export * from "d3-zoom";
export * from "d3-scale";
export * from "d3-drag";
export * from "d3-force";
export * from "d3-axis";
package.json
{
...
"scripts": {
"prepublish": "rollup -c && uglifyjs dist/d3.js -c -m -o dist/d3.min.js"
},
...
}
webpack.config.js
module.exports = {
...
resolve: {
alias: {
'd3': path.resolve(__dirname, 'dist/d3.min.js')
}
},
...
};
So for background originally I was excluding the node_modules directory in my Webpack config, which was working fine for my sass #import statements, but made it very difficult to include things from the node_modules directory. So I switched the SASS loader to the following
{
test: /\.scss$/,
include: [path.resolve(__dirname, "/src/client"), path.resolve(__dirname, "/node_modules/angular-material/")],
loader: 'style-loader!css-loader!autoprefixer-loader!sass-loader'
},
Please also note I tried with and without the trailing slash on client.
All my src files including the sass files are in ./src/client directory including sub-directories. The problem now is when I run Webpack all my import statements are no longer functional. and I end up with the following error whenever I try to import one of my own sass files:
ERROR in ./src/client/app/app.scss
Module parse failed: /Users/mikedklein/development/vncuxf/src/client/app/app.scss Line 1: Unexpected token ILLEGAL
You may need an appropriate loader to handle this file type.
| #import 'common/common';
| #import 'general';
|
# ./src/client/app/app.module.es6 85:0-21
If I comment out the include statement all is well, but I know this is not a good approach. For reference I have also included my resolve statement from my config:
// Resolves so require statements don't need extentions
resolve: {
extensions: ['', '.js', '.es6', '.scss', '.css', '.html', '.json'],
alias: {
angular_material_scss: __dirname + "/node_modules/angular-material/angular-material.scss"
}
}
So I think I solved this
module: {
loaders: [
{
test: /\.(es6|js)$/,
exclude: /node_module/,
loader: 'babel-loader'
},
{
test: /\.css$/,
exclude: /node_modules/,
loader: 'style-loader!css-loader!autoprefixer-loader'
},
{
test: /\.scss$/,
loader: 'style-loader!css-loader!autoprefixer-loader!sass loader'
}
]
},
// This is the key need to have include paths in the sass loader option.
sassLoader: {
includePaths: [path.resolve(__dirname, './src/app'), path.resolve(__dirname, '/node_modules/angular-material')]
}
One thing I am still curious about is whether this is the most efficient approach, when sass files are stored in multiple directories.