Reputation: 445
I'm struggling to get webpack to do what I want here. Basically, I'm trying to feed in two CSS files and an SCSS file, and output one CSS file from this.
My code so far is:
'use strict';
var webpack = require('webpack');
var webpackDir = __dirname;
let path = require('path');
let nodeModulesPath = path.join(webpackDir, 'node_modules');
//Process the SCSS
var ExtractTextPlugin = require('extract-text-webpack-plugin');
let extractCSS = new ExtractTextPlugin('../css/[name].css',{allChunks: true});
function isDev() {
var isDev = true;
if (process.env.NODE_ENV === 'production') {
isDev = false;
}
return isDev;
}
var definePlugin = new webpack.DefinePlugin({
__DEV__: isDev()
});
module.exports = {
resolve: {
modulesDirectories: [webpackDir + '/node_modules'],
alias: {
rootReducers: path.join(webpackDir, '../../../../../themes/myProject-base/lib/myProject-core/register/myProject-redux-base/base-reducers'),
rootActions: path.join(webpackDir, '../../../../../themes/myProject-base/lib/myProject-core/register/myProject-redux-base/base-actions'),
rootUtils: path.join(webpackDir, '../../../../../themes/myProject-base/lib/myProject-core/register/myProject-redux-base/base-utils'),
lunchMenusReducers: path.join(webpackDir, '/src/lunch-menus-common-js/reducers/lunch-menus-reducers'),
lunchMenusActions: path.join(webpackDir, '/src/lunch-menus-common-js/actions/lunch-menus-actions'),
lunchMenusConfigureStore: path.join(webpackDir, '/src/lunch-menus-common-js/configureStore')
}
},
resolveLoader: {
root: nodeModulesPath
},
entry: {
backend: path.resolve(webpackDir + '/src/components/index.js'),
widgetfrontend: path.join(webpackDir, '../../../includes/widget/public-js/scripts/main.js'),
widgetbackend: path.join(webpackDir, '../../../includes/widget/js/scripts/main.js'),
myProjectLunchMenusAdmin: [
path.join(webpackDir, '../../scss/myProject-lunch-menus-admin.scss'),
path.join(nodeModulesPath + 'react-datepicker/dist/react-datepicker.min.css'),
path.join(nodeModulesPath + 'node_modules/quill/dist/*.css')
]
},
output: {
path: path.resolve(webpackDir + '/../'),
filename: '[name].js',
devtoolLineToLine: true
},
plugins: isDev() !== true ? [
extractCSS,
new webpack.optimize.UglifyJsPlugin({minimize: true}),
definePlugin
] : [
extractCSS,
definePlugin
],
module: {
loaders: [
{
test: /(src|myProject-base|widget)\/.+.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: [
require.resolve('babel-preset-es2015'),
require.resolve('babel-preset-react'),
require.resolve('babel-preset-stage-0')
]
}
},
{
test: /\.scss$/i,
loader: extractCSS.extract(['css','sass'])
},
{
test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$/,
exclude: /node_modules/,
loader: 'file'
}
]
}
}
The area of focus is myProjectLunchMenusAdmin
- as it's not taking in the CSS + SCSS files and outputting one CSS file.
The error(s) I get are:
ERROR in multi myProjectLunchMenusAdmin
Module not found: Error: Cannot resolve 'file' or 'directory' /Users/joneslloyd/Documents/MAMP/myProjectv2/wp-content/plugins/myProject-lunch-menus/admin/js/scripts/node_modules/node_modules/quill/dist/*.css in /Users/joneslloyd/Documents/MAMP/myProjectv2/wp-content/plugins/myProject-lunch-menus/admin/js/scripts
@ multi myProjectLunchMenusAdmin
ERROR in ./~/react-datepicker/dist/react-datepicker.min.css
Module parse failed: /Users/joneslloyd/Documents/MAMP/myProjectv2/wp-content/plugins/myProject-lunch-menus/admin/js/scripts/node_modules/react-datepicker/dist/react-datepicker.min.css Line 1: Unexpected token .
You may need an appropriate loader to handle this file type.
At this stage, even a pointer/suggestion would be really useful!
Upvotes: 1
Views: 2341
Reputation: 17805
There are several issues with this config.
modulesDirectories
should be an array of directory names that will be resolved like node_modules
(that is: traversing the directory tree and looking for a node_modules
folder). Do not put actual paths in this array. This is one of the most common errors I see in webpack configs. Since npm is the most prominent package manager, you usually don't need to set this option as it already defaults to node_modules
.
The named chunk myProjectLunchMenusAdmin
references CSS files, but you did not activate the css-loader for the .css
extension. That's basically what the Module parse failed
error is trying to say.
The named chunk myProjectLunchMenusAdmin
references the glob pattern node_modules/quill/dist/*.css
. Webpack does not understand glob patterns. In your case, it tries to include a file actually named *.css
which is what the Module not found
error is trying to tell. You need to pass webpack only one file and webpack will figure out the dependency graph. For example: If file main.css
imports some-other-file.css
, it will include that file too and so on. By doing that, webpack will only include files that are actually needed because they are referenced in your program. (Btw: node_modules/node_modules
does not look correct)
Using a relative path for the first argument of the ExtractTextPlugin
is probably invalid. I don't know if that actually works. You should just give a filename and webpack will emit the extracted and unified CSS into a file with that name in the specified output.path
. The output.path
is usually a flat folder without sub-directories. If you need to move the bundled files around afterwards, you should separate that from your webpack build. That's just another build step.
resolveLoader.root
does not need to be modified as long as you're installing your loaders via npm (which I strongly recommend).
I've tried to fix the given config. Since I don't know your project, there is not guarantee that this will work.
'use strict';
let webpack = require('webpack');
let path = require('path');
let nodeModulesPath = path.join(__dirname, 'node_modules');
//Process the SCSS
let ExtractTextPlugin = require('extract-text-webpack-plugin');
let extractCSS = new ExtractTextPlugin('[name].css',{allChunks: true});
let isDev = process.env.NODE_ENV !== 'production';
var definePlugin = new webpack.DefinePlugin({
__DEV__: isDev
});
module.exports = {
resolve: {
alias: {
rootReducers: path.join(__dirname, '../../../../../themes/myProject-base/lib/myProject-core/register/myProject-redux-base/base-reducers'),
rootActions: path.join(__dirname, '../../../../../themes/myProject-base/lib/myProject-core/register/myProject-redux-base/base-actions'),
rootUtils: path.join(__dirname, '../../../../../themes/myProject-base/lib/myProject-core/register/myProject-redux-base/base-utils'),
lunchMenusReducers: path.join(__dirname, 'src/lunch-menus-common-js/reducers/lunch-menus-reducers'),
lunchMenusActions: path.join(__dirname, 'src/lunch-menus-common-js/actions/lunch-menus-actions'),
lunchMenusConfigureStore: path.join(__dirname, 'src/lunch-menus-common-js/configureStore')
}
},
entry: {
backend: path.join(__dirname, 'src/components/index.js'),
widgetfrontend: path.join(__dirname, '../../../includes/widget/public-js/scripts/main.js'),
widgetbackend: path.join(__dirname, '../../../includes/widget/js/scripts/main.js'),
myProjectLunchMenusAdmin: [
path.join(__dirname, '../../scss/myProject-lunch-menus-admin.scss'),
path.join(nodeModulesPath, 'react-datepicker/dist/react-datepicker.min.css'),
path.join(nodeModulesPath, 'quill/dist/quill.base.css'),
path.join(nodeModulesPath, 'quill/dist/quill.snow.css')
]
},
output: {
path: path.resolve(__dirname, '..'),
filename: '[name].js',
devtoolLineToLine: true
},
plugins: [
extractCSS,
definePlugin
].concat(isDev ? [
] : [
new webpack.optimize.UglifyJsPlugin({minimize: true})
]),
module: {
loaders: [
{
test: /(src|myProject-base|widget)\/.+.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: [
require.resolve('babel-preset-es2015'),
require.resolve('babel-preset-react'),
require.resolve('babel-preset-stage-0')
]
}
},
{
test: /\.css$/i,
loader: extractCSS.extract(['css'])
},
{
test: /\.scss$/i,
loader: extractCSS.extract(['css','sass'])
},
{
test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$/,
loader: 'file'
}
]
}
}
Upvotes: 1