Webpack compile sass into css file problem - sass

Firstly I'd like to say that I've seen same question but I cannot upvote nor comment to say that I'm in the same need. So it's clearly a duplicate of How to use Webpack 4 to compile Sass files properly?
I'm just trying to compile some sass file into css file using webpack. But webpack creates some useless js files with the same name as the css files.
The folder Structure:
--dist
--src
|--a
|--editor.scss
|--style.scss
|--b
|--editor.scss
|--style.scss
and my dependencies (package.json)
"devDependencies": {
"webpack": "latest",
"webpack-cli": "latest",
"css-loader": "latest",
"sass-loader": "latest",
"node-sass": "latest",
"mini-css-extract-plugin": "latest"
}
here the config I've set up already (webpack.config.js):
const path = require("path");
const context = path.resolve(__dirname);
const output = context + "/dist";
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const entries = {
"/dist/a/editor": "./src/a/editor.scss",
"/dist/a/style": "./src/a/style.scss",
"/dist/b/editor": "./src/b/editor.scss",
"/dist/b/style": "./src/b/style.scss"
};
module.exports = {
context: context,
entry: entries,
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css"
})
],
output: {
path: output
// // publicPath: distBlocks,
// // filename: "[name].js"
},
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: "css-loader"
},
{
loader: "sass-loader"
}
]
}
]
}
};
Actual result:
--dist
|--a
|--editor.css
|--editor.js
|--style.css
|--style.js
|--b
|--editor.css
|--editor.js
|--style.css
|--style.js
--src
|--a
|--editor.scss
|--style.scss
|--b
|--editor.scss
|--style.scss
Expected result is the same without those useless js files...
So How webpack is suppose to be configured to get the css file only and no js files from the scss??
UPDATE:
Here is a workaround : webpack-fix-style-only-entries
webpack.config.js
...
const FixStyleOnlyEntriesPlugin = require("webpack-fix-style-only-entries");
...
Module.exports = {
...
plugins: [
new FixStyleOnlyEntriesPlugin(),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css"
})
],
...
There is a fix but only for the future version of webpack (^5) if understood correctly webpack git

Related

How to configure Next.js with Antd / Less and Sass / CSS modules

I want to use Next.js with Sass and CSS modules but also want to use Ant Design and wanted to use the Less styles for smaller building size.
I'm able to enable either CSS modules or Less loader but not both at the same time. The examples from Next.js were not helping me complete that problem.
Edit: This answer is definitely outdated for current versions of next.js, check the other answers below.
After multiple hours of research I found now finally the right solution and wanted to share it:
.babelrc (no magic here)
{
"presets": ["next/babel"],
"plugins": [
[
"import",
{
"libraryName": "antd",
"style": true
}
]
]
}
next.config.js:
/* eslint-disable */
const withLess = require('#zeit/next-less');
const withSass = require('#zeit/next-sass');
const lessToJS = require('less-vars-to-js');
const fs = require('fs');
const path = require('path');
// Where your antd-custom.less file lives
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, './assets/antd-custom.less'), 'utf8')
);
module.exports = withSass({
cssModules: true,
...withLess({
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables, // make your antd custom effective
importLoaders: 0
},
cssLoaderOptions: {
importLoaders: 3,
localIdentName: '[local]___[hash:base64:5]'
},
webpack: (config, { isServer }) => {
//Make Ant styles work with less
if (isServer) {
const antStyles = /antd\/.*?\/style.*?/;
const origExternals = [...config.externals];
config.externals = [
(context, request, callback) => {
if (request.match(antStyles)) return callback();
if (typeof origExternals[0] === 'function') {
origExternals[0](context, request, callback);
} else {
callback();
}
},
...(typeof origExternals[0] === 'function' ? [] : origExternals)
];
config.module.rules.unshift({
test: antStyles,
use: 'null-loader'
});
}
return config;
}
})
});
The final hint how to write the withSass withLess use and to put the cssModules: true in the outer object came from this comment here.
While I was already trying different combinations derived from the examples before:
next+ant+less
next+sass
For completion here the dependencies in my package.json:
...
"dependencies": {
"#zeit/next-less": "^1.0.1",
"#zeit/next-sass": "^1.0.1",
"antd": "^4.1.3",
"babel-plugin-import": "^1.13.0",
"less": "^3.11.1",
"less-vars-to-js": "^1.3.0",
"next": "^9.3.4",
"node-sass": "^4.13.1",
"null-loader": "^3.0.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"sass": "^1.26.3"
}
...
I hope this helps other people to find this solution faster. :)
#zeit/next-less is deprecated and disables Next's built in CSS support. It also uses a very old version of less and less-loader.
I created a package that injects Less support to Next.js by duplicating the SASS rules and setting them for Less files and less-loader. It works with webpack5 flag.
https://github.com/elado/next-with-less
https://www.npmjs.com/package/next-with-less
While the above answers may work for versions of NextJS lower than 11, they do not work for 11+. I've found excellent success with the following plugin...
https://github.com/SolidZORO/next-plugin-antd-less
I am using elado's package which is -
https://github.com/elado/next-with-less
you will need less and less-loader as dependencies.
after that create a global.less file on styles folder. so it's like ,root> style > global.less and paste this code
#import '~antd/lib/style/themes/default.less';
#import '~antd/dist/antd.less';
#primary-color: #ff9b18;
#border-radius-base: 20px;
and add below code in your next.config.js file which you will create on your root folder.
// next.config.js
const withLess = require("next-with-less");
module.exports = withLess({
lessLoaderOptions: {
/* ... */
},
});
To add Less to the Next.js is easy way.
Need to add 'next-with-less' library (also install less and less-loader) and 'next-compose-plugin'.
To your next.config.js add:
/** #type {import('next').NextConfig} */
const withPlugins = require('next-compose-plugins');
const withLess = require('next-with-less');
const plugins = [
[
withLess,
{
lessLoaderOptions: {},
},
],
];
module.exports = withPlugins(plugins, {
reactStrictMode: true,
swcMinify: true,
});
In our project, there were old scss and css files. They were not using the Next js guidline for CSS modules. So I had to override webpack.config.js. So that works fine. But when we moved the file to the monorepo shared package, babel was not transpiling them. I used the below things, but those did not work for SCSS modules without a .module extension.
next-transile-module.
experimental: { externalDir: true, } in next Js config with root babel.cofig.json
Finally symlink hack worked for external shared files
Use symlinks for shared folder by updating next.config.js
module.exports = {
//...
resolve: {
symlinks: false,
},
};
For anyone who is still having trouble, you don't need any extra package other than our lovely mini-css-extract-plugin. Here is how you solve the issue.
PS: I also added sass to my webpack config. You can use both less and sass/scss files in your project.
next.config.js:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
webpack(config) {
config.module.rules.push(
{
// this part is for css
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, { loader: 'css-loader' }],
},
{
// this part is for sass
test: /\.module\.(scss|sass)$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader' },
{ loader: 'sass-loader' },
],
},
{
// this part is for less
test: /\.less$/i,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
},
{
loader: 'less-loader',
options: {
sourceMap: true,
lessOptions: {
javascriptEnabled: true,
},
},
},
],
}
);
config.plugins.push(
new MiniCssExtractPlugin({
filename: 'static/css/[name].css',
chunkFilename: 'static/css/[contenthash].css',
})
);
return config;
},
};
package.json:
"dependencies": {
"#next/font": "13.1.1",
"css-loader": "^6.7.3",
"less": "^4.1.3",
"less-loader": "^11.1.0",
"mini-css-extract-plugin": "^2.7.2",
"next": "13.1.1",
"next-transpile-modules": "^10.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"sass": "^1.57.1",
"sass-loader": "^13.2.0",
}

errors when creating webpack config file

I am trying to setup the simplest possible typescript+react-project in visual studio 2017.
I have this webpack.config.js that was changed to work with webpack 2+
The change was from using "loaders" and "preloaders" to "rules".
With the content below I get the error
Module build failed: error TS5014: Failed to parse file 'C:\Users\my project\tsconfig.json': Unexpected token } in JSON at position 4521.
This is the file
module.exports = {
entry: "./Scripts/hello-stackoverflow/index.tsx",
output: { filename: "./dist/bundle.js" },
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
{ test: /\.tsx?$/, loader: "ts-loader" },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
]
},
externals: {
"react": "React",
"react-dom": "ReactDOM"
}
};

Laravel + VueJs + Webpack + Karma = world of pain

Is it possible to write unit tests for VueJs if you are using Laravel's Elixir for your webpack configuration?
VueJs 2x has a very simple example for a component test: Vue Guide Unit testing
<template>
<span>{{ message }}</span>
</template>
<script>
export default {
data () {
return {
message: 'hello!'
}
},
created () {
this.message = 'bye!'
}
}
</script>
and then...
// Import Vue and the component being tested
import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'
describe('MyComponent', () => {
it('has a created hook', () => {
expect(typeof MyComponent.created).toBe('function')
})
it ...etc
})
and gives an example of a karma conf file here: https://github.com/vuejs-templates
But the Karma configuration file requires a webpack configuration file
webpack: webpackConfig,
The only problem is the Laravel's Elixir is creating the webpack configuration so it can't be included.
I have tried creating another webpack configuration file based on the example from https://github.com/vuejs-templates/webpack.
Something like this:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
// the "scss" and "sass" values for the lang attribute to the right configs here.
// other preprocessors should work out of the box, no loader config like this necessary.
'scss': 'vue-style-loader!css-loader!sass-loader',
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
and included it like...
// Karma configuration
// Generated on Wed Mar 15 2017 09:47:48 GMT-0500 (CDT)
var webpackConf = require('./karma.webpack.config.js');
delete webpackConf.entry;
module.exports = function(config) {
config.set({
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
But I am getting errors that seem to indicate that webpack isn't doing anything.
ERROR in ./resources/assets/js/components/test.vue
Module parse failed: /var/www/test/resources/assets/js/components/test.vue Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| <template>
| <span >{{test}}</span>
| </template>
Ok, I got this to work. Couple of things that might help.
I was originally running gulp, and trying to run tests in my vagrant box, to try to match the server configuration. I think that makes it much harder to find examples and answers on the internet.
Ok, so the main problem I was having is that webpack wasn't processing my components included in my test files. I copied the webpack config out of the laravel-elixir-vue-2/index.js node module directly into the Karma configuration file and it started working.
The key is that karma-webpack plugin needs both the resolve and module loader configuration settings (resolve with alias and extensions) for it to work.
Hope this helps someone.
karma.conf.js:
module.exports = function (config) {
config.set({
// to run in additional browsers:
// 1. install corresponding karma launcher
// http://karma-runner.github.io/0.13/config/browsers.html
// 2. add it to the `browsers` array below.
browsers: ['Chrome'],
frameworks: ['jasmine'],
files: ['./index.js'],
preprocessors: {
'./index.js': ['webpack']
},
webpack: {
resolve: {
alias: {
vue: 'vue/dist/vue.common.js'
},
extensions: ['.js', '.vue']
},
vue: {
buble: {
objectAssign: 'Object.assign'
}
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'file-loader',
query: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: '../fonts/[name].[hash:7].[ext]'
}
}
]
}
},
webpackMiddleware: {
noInfo: true,
},
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' },
]
},
});
};
I ran into the exact same problem. The accepted answer did not fully work for me. The following solved my issue:
Install relevant loaders for webpack:
npm install --save-dev vue-loader file-loader url-loader
Create webpack config file (note the format). The accepted answer produced errors citing invalid format of the webpack.config.js file. At least with me it did.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: [
{ loader: 'vue-loader' }
]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'file-loader',
query: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
}
]
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: [
{
loader: 'url-loader',
query: {
limit: 10000,
name: '../fonts/[name].[hash:7].[ext]'
}
}
]
}
]
}
}
karma.conf.js
// Karma configuration
var webpackConf = require('./webpack.config.js');
delete webpackConf.entry
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
port: 9876, // web server port
colors: true,
logLevel: config.LOG_INFO,
reporters: ['progress'], // dots, progress
autoWatch: true, // enable / disable watching files & then run tests
browsers: ['Chrome'], //'PhantomJS', 'Firefox',
singleRun: true, // if true, Karma captures browsers, runs the tests and exits
concurrency: Infinity, // how many browser should be started simultaneous
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
/**
* base path that will be used to resolve all patterns (eg. files, exclude)
* This should be your JS Folder where all source javascript
* files are located.
*/
basePath: './resources/assets/js/',
/**
* list of files / patterns to load in the browser
* The pattern just says load all files within a
* tests directory including subdirectories
**/
files: [
{pattern: 'tests/*.js', watched: false},
{pattern: 'tests/**/*.js', watched: false}
],
// list of files to exclude
exclude: [
],
/**
* pre-process matching files before serving them to the browser
* Add your App entry point as well as your Tests files which should be
* stored under the tests directory in your basePath also this expects
* you to save your tests with a .spec.js file extension. This assumes we
* are writing in ES6 and would run our file through babel before webpack.
*/
preprocessors: {
'app.js': ['webpack', 'babel'],
'tests/**/*.spec.js': ['babel', 'webpack']
},
})
}
Then run karma start and everything should work.

Webpack, sass being overwriten

I'll start by saying I have a bit of a bizarre webpack build. I have 2 projects, the main project and the shared project (like a common library).
Whenever I refer to my shared project from the main project, it get some bizarre IE only/react/webpack build error where I get an error when trying to refer to my shared library. To solve this, I aliased my shared library references to the actual source on my computer in a different folder. That looks something like this:
var alias.shared-library = 'c:\\shared-library\\index.js';
This fixed my bizarre IE problem. However, another issue raised in my webpack production build. On the production server, the shared library exists within the node_modules folder, so I tried something like this:
var alias.shared-library = 'node_modules\\shared-library\\index.js';
It mostly works, except all my scss from the main project is overwritten by scss from the shared project (the output css only contains scss from the shared lib and not main). My full setup looks something like this (I removed parts I thought weren't important):
var SHARED_PATH = path.resolve(__dirname, 'node_modules/shared-library');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractCss = new ExtractTextPlugin('css.styles.css');
const extractScss = new ExtractTextPlugin('scss.styles.css');
const plugs = [];
plugs.push(
new webpack.DefinePlugin({
__DEVELOPMENT__: false
})
);
plugs.push(
new HtmlWebpackPlugin({
template: './index.html',
inject: 'body',
chunks: ['app', 'vendor']
})
);
plugs.push(new webpack.NoErrorsPlugin());
plugs.push(
new CopyWebpackPlugin([
{ from: 'src/assets', to: 'assets' },
])
);
plugs.push(
new SplitByPathPlugin([
{ name: 'vendor', path: [path.join(__dirname, 'node_modules')] },
])
);
plugs.push(extractCss);
plugs.push(extractScss);
plugs.push(
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
})
);
var alias = {
'shared-library': path.resolve(SHARED_PATH, '\\src\\index.js')
};
var loaderDirs = ['node_modules', 'webpack_loaders'];
var moduleDirs = ['node_modules', 'src'];
loaderDirs.push(SHARED_PATH + '\\node_modules');
moduleDirs.push(SHARED_PATH + '\\node_modules');
moduleDirs.push(SHARED_PATH + '\\src');
module.exports = {
entry: {
app: ['./src/index.js']
},
resolve: {
extensions: ['', '.js', '.scss', '.css'],
modulesDirectories: moduleDirs,
alias
},
resolveLoader: {
modulesDirectories: loaderDirs
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].[hash].js',
publicPath: '/main/',
sourceMapFilename: '[name].[hash].js.map',
chunkFilename: '[id].chunk.js',
},
plugins: plugs,
module: {
loaders: [
{
test: /\.js?$/,
loader: 'babel?sourceMaps=true',
include: [/src/, path.resolve(SHARED_PATH, '\\src\\index.js')]
},
{
test: /\.css$/,
loader: extractCss.extract('style', 'css')
},
{
test: /\.scss$/,
loader: extractScss.extract('style', 'css!sass'),
include: /src/ // Trying to exclude scss from shared-library, doesn't work though
},
loaders.json,
loaders.image,
loaders.svg,
loaders.font,
loaders.locale,
loaders.html
]
},
postcss: (webpack) => {
return [
autoprefixer({
browsers: ['last 2 versions'],
}),
postcssImport({
addDependencyTo: webpack,
})
];
},
externals: {
'react/lib/ReactContext': 'window',
'react/lib/ExecutionEnvironment': 'window',
'react/addons': true
}
};
I've tried things like different permutations of exclude/include on my loaders. I thought the allChunks option on ExtractTextPlugin might work:
const extractScss = new ExtractTextPlugin({filename: 'scss.styles.css', allChunks: true});
but it just gives me this error:
TypeError: path.replace is not a function
at Template.replacePathVariables (c:\r2\RCA\rca-ui\node_modules\webpack\lib\
TemplatedPathPlugin.js:70:4)
at Template.applyPlugins [as applyPluginsWaterfall] (c:\r2\RCA\rca-ui\node_m
odules\webpack\node_modules\tapable\lib\Tapable.js:37:47)
at Compilation.getPath (c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compilatio
n.js:882:27)
at ExtractTextPlugin.<anonymous> (c:\r2\RCA\rca-ui\node_modules\extract-text
-webpack-plugin\index.js:300:29)
at Array.forEach (native)
at ExtractTextPlugin.<anonymous> (c:\r2\RCA\rca-ui\node_modules\extract-text
-webpack-plugin\index.js:289:20)
at Compilation.next (c:\r2\RCA\rca-ui\node_modules\webpack\node_modules\tapa
ble\lib\Tapable.js:69:14)
at ExtractTextPlugin.<anonymous> (c:\r2\RCA\rca-ui\node_modules\extract-text
-webpack-plugin\index.js:309:4)
at Compilation.applyPluginsAsync (c:\r2\RCA\rca-ui\node_modules\webpack\node
_modules\tapable\lib\Tapable.js:71:13)
at Compilation.<anonymous> (c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compil
ation.js:563:8)
at Compilation.next (c:\r2\RCA\rca-ui\node_modules\webpack\node_modules\tapa
ble\lib\Tapable.js:67:11)
at ExtractTextPlugin.<anonymous> (c:\r2\RCA\rca-ui\node_modules\extract-text
-webpack-plugin\index.js:285:5)
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modules\as
ync\lib\async.js:52:16
at done (c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modu
les\async\lib\async.js:246:17)
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modules\as
ync\lib\async.js:44:16
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\index.js:269:6
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modules\as
ync\lib\async.js:52:16
at done (c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modu
les\async\lib\async.js:246:17)
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modules\as
ync\lib\async.js:44:16
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\index.js:259:9
at c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compilation.js:469:4
at Array.forEach (native)
at callback (c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compilation.js:468:14
)
at Compilation.<anonymous> (c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compil
ation.js:489:4)
at c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compilation.js:332:10
at c:\r2\RCA\rca-ui\node_modules\webpack\node_modules\async\lib\async.js:52:
16
at Object.async.forEachOf.async.eachOf (c:\r2\RCA\rca-ui\node_modules\webpac
k\node_modules\async\lib\async.js:236:30)
at Object.async.forEach.async.each (c:\r2\RCA\rca-ui\node_modules\webpack\no
de_modules\async\lib\async.js:209:22)
at Compilation.addModuleDependencies (c:\r2\RCA\rca-ui\node_modules\webpack\
lib\Compilation.js:185:8)
at Compilation.processModuleDependencies (c:\r2\RCA\rca-ui\node_modules\webp
ack\lib\Compilation.js:170:7)
Any ideas on the proper approach to solve this problem? Would the allChunks option help me here? Do I need to tighten up my include/excludes? Is there something else I'm missing? Should I give up and try and fix the IE problem another way? Is there a way I can debug what is happening? Here's the versions of the libraries I am using:
"extract-text-webpack-plugin": "1.0.1",
"style-loader": "0.13.0",
"sass-loader": "3.1.2",
"webpack": "1.13.2"
Thanks

Using Slick-Carousel and NPM

Still trying to master NPM and hit some roadblocks.
My slick-carousel works great when I use the CDN process. But I'm doing everything in NPM so figured I should do the same with this plug-in, but can't seem to get it off the ground.
Ran the install:
npm install slick-carousel --save
Which adds to my package.json file:
"devDependencies": {
"copy-webpack-plugin": "^3.0.1",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.9.0",
"gh-pages": "^0.11.0",
"html-webpack-plugin": "^2.21.0",
"img-loader": "^1.3.1",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"webpack": "^1.13.1"
},
"dependencies": {
"font-awesome-webpack": "0.0.4",
"jquery": "^3.0.0",
"slick-carousel": "^1.6.0"
}
I'm smart enough to know that I need to require the file in my index.js file:
var $ = require('jquery');
require("../css/style.css");
require("font-awesome-webpack");
require("slick-carousel");
I can see that I now have all the jQuery for slick-carousel, but none of the css.
Now I figure I should require the two .css files living in the node_modules folder:
require("slick-carousel/slick/slick.css");
require("slick-carousel/slick/slick-theme.css");
And this is where it all breaks. The slick.css file loads and the basic slick-carousel is now working in my html output. But the slick-theme file breaks everything by pushing this error:
./~/slick-carousel/slick/ajax-loader.gif
Module parse failed: /Users/ryanbuchholtz/Documents/thinkful/haventower/node_modules/slick-carousel/slick/ajax-loader.gif Unexpected character '' (1:7)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected character '' (1:7)
This makes me think something is broken in my webpack.config.js:
var path = require('path');
var packageData = require('./package.json');
var filename = [packageData.name, packageData.version, 'js'];
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var CopyWebpackPlugin = require('copy-webpack-plugin');
var plugins = [
new HtmlWebpackPlugin({
inject: 'head',
template: 'index.html',
minify: {
"collapseWhitespace": true,
"removeComments": true,
"removeRedundantAttributes": true,
"removeScriptTypeAttributes": true,
"removeStyleLinkTypeAttributes": true
}
}),
new ExtractTextPlugin('style.css')
];
module.exports = {
entry: {
main: [
path.resolve(__dirname, packageData.main)
]
},
output: {
path: path.resolve(__dirname, 'build'),
filename: filename.join('.'),
},
devtool: 'source-map',
plugins: plugins,
module: {
loaders: [
{
test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader", "file-loader")
},
{ test: /\.(jpe?g|png|gif|svg)$/, loader: "file-loader"
},
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&minetype=application/font-woff"
},
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader"
}
]
}
};
I could really use some assistance in the best way to use slick-carousel while building in NPM and with webpack. So many moving pieces and, when I kinda think I get it, this comes along and I spend 7 hours trying to fix it before asking for help.
Any help is deeply appreciated.
I had the same issue, but I didn't want to change slick-carousel in my project, so one month late but here is how I solved it:
First install Webpack image-loader:
$ npm install image-webpack-loader --save-dev
Then change these lines (in your webpack configuration):
loaders: [{
test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader", "file-loader")
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'file?hash=sha512&digest=hex&name=[hash].[ext]',
'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false'
]
},
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&minetype=application/font-woff" },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader"
}]
This will change file-loader (what you are using for loading images) for image-loader, it will know how to compile .gif files and other formats.
For aditional information about this, you can check the github page
Also, if you are using ReactJS, don't use slick-carousel directly, because it uses direct DOM manipulation thanks to JQuery dependency, right now I'm using react-slick is very stable and has cool options like settings based on responsive layout custom prev and next arrows and more.
I hope it help you
require("slick-carousel/slick/slick.css");
require("slick-carousel/slick/slick-theme.css");
From what I understand you do not need both of these - only one.
Slick-theme is the default CSS, while Slick you integrate.
I could be wrong (I'm really new to development) but I've had no problems with the initial configuration!

Resources