Compile scss with webpack for an Angular App - javascript

I'm using webpack 3 for my angular app. I have some issues with compiling my scss files. Here is full webpack config file:
const path = require('path')
const autoprefixer = require('autoprefixer')
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const config = {
context: __dirname + '/src',
entry: {
app: './index.js',
vendor: [
'angular',
'angular-animate',
'angular-bootstrap',
'angular-route',
'animate',
'bootstrap',
'bootstrap-filestyle',
'jquery',
'ng-file-upload',
'ng-parallax'
]
},
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'app'),
publicPath: path.join(__dirname, 'app')
},
resolve: {
extensions: ['.js', '.jsx', '.scss']
},
module: {
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader',
'css?minimize!postcss!sass')
},
{
test: /\.(eot|woff|woff2|ttf|svg)(\?\S*)?$/,
loader: 'file?name=fonts/[name].[ext]'
},
{
test: /\.(jpg|jpeg|gif|png|svg)$/,
loader: 'file?name=images/[name].[ext]'
}
],
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
},
{
test: /\.svg$/,
loader: 'url-loader'
},
{
test: /\.php$/,
loader: 'file-loader?name=[name].[ext]'
},
{
test: /\.zip$/,
loader: 'file-loader?name=[name].[ext]'
},
{
test: /(\.png|\.jpg|\.gif)$/,
loader: 'file-loader?name=[path][name].[ext]'
}
]
},
plugins: [
new ExtractTextPlugin('./bundle.css'),
new CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.bundle.js'
}),
new UglifyJSPlugin({})
// new ExtractTextPlugin({
// filename: '[name].min.css'
// })
]
}
module.exports = config
After running webpack i've got this error:
ERROR in ./assets/sass/main.scss
Module parse failed: /home/git/project/src/public/src/assets/sass/main.scss Unexpected token (1:13)
You may need an appropriate loader to handle this file type.
| $header-color: #ffffff;
| $admin-panel-height: 40px;
|
# ./index.js 3:0-34
Also i tried to use this loader: https://github.com/webpack-contrib/sass-loader
After webpack build there no errors appeared, but css file also was not created in /app folder.
file main.scss imports in index.js:
import './assets/sass/main.scss'
Can anyone give me an advice how can i build and watch scss files with webpack 3 ?

You have used some of the loader configs that suppose to be for webpack 1.
That section of the config:
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader',
'css?minimize!postcss!sass')
},
{
test: /\.(eot|woff|woff2|ttf|svg)(\?\S*)?$/,
loader: 'file?name=fonts/[name].[ext]'
},
{
test: /\.(jpg|jpeg|gif|png|svg)$/,
loader: 'file?name=images/[name].[ext]'
}
],
There are breaking changes when you move to Webpack 2 (or 3).
One of them was module.loaders => module.rules.
You will need to convert that section to the new structure.
In addition, ExtractTextPlugin changes it config style as well, please read it README.

Related

Issue with integrating cortex-js/compute machine in react application

I am trying to use compute machine provided by the cortexjs. https://cortexjs.io/compute-engine
I saved this dependency using
npm i #cortex-js/compute-engine
After I ran npm start, I am getting this error:
ERROR in ./node_modules/#cortex-js/compute-engine/dist/compute-engine.min.js 2:1360
Module parse failed: Unexpected token (2:1360)
You may need an appropriate loader to handle this file type.
Following is my webpack file:
var webpack = require('webpack');
const HtmlWebPackPlugin = require("html-webpack-plugin");
var path = require('path');
module.exports = {
// output: {
// path: path.resolve(__dirname, 'dist'),
// filename: 'main.js',
// publicPath: '/'
// },
mode : 'production',
devServer: {
historyApiFallback: true,
},
devtool: "source-map",
module: {
rules: [
{
test: /\.(png|jpg|woff|woff2|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader"
}
]
},
{
test: /\.css$/,
loader: 'style-loader'
},
{
test: /\.css$/,
loader: 'css-loader',
options: {
import: true,
},
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
})
]
};
Please can someone suggest which loader should I add to webpack.config file to make this work.

Click to open PDF - You may need an appropriate loader to handle this file type

I'm trying to import a PDF into a .js file in order to have a Click to open pdf into my render.
Importing
import myFile from './assets/files/myfile.pdf';
Rendering
render() {
return (
...
<a href={myFile}>
<span>Click to open PDF</span>
</a>
...
)}
Error
myProject.bundle.js:88481 ./assets/files/myfile.pdf 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
Webpack.config.js
I tried several PDF loader without success, the webpack below uses url-loader.
const path = require('path'),
webpack = require('webpack'),
CleanWebpackPlugin = require('clean-webpack-plugin'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractPlugin = new ExtractTextPlugin({ filename: './assets/css/app.css' });
const config = {
mode: 'production',
// absolute path for project root with the 'src' folder
context: path.resolve(__dirname, 'src'),
entry: ['babel-polyfill', './main.js'],
// entry: {
// // relative path declaration
// app: './main.js'
// },
output: {
// absolute path declaration
path: path.resolve(__dirname, 'dist'),
filename: 'myProject.bundle.js',
publicPath: '/'
},
module: {
rules: [
// ************
// * SEE HERE *
// ************
{ test: /\.pdf$/, use: 'url-loader' },
// babel-loader with 'env' preset
{ test: /\.jsx?$/, include: /src/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: ['env', 'es2015', 'react', 'stage-0'] } } },
// html-loader
{ test: /\.html$/, use: ['html-loader'] },
// sass-loader with sourceMap activated
{
test: /\.scss$/,
include: [path.resolve(__dirname, 'src', 'assets', 'scss')],
use: extractPlugin.extract({
use: [
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
],
fallback: 'style-loader'
})
},
// file-loader(for images)
{ test: /\.(jpg|png|gif|svg)$/, use: [ { loader: 'file-loader', options: { name: '[name].[ext]', outputPath: './assets/images/' } } ] },
// file-loader(for fonts)
{ test: /\.(woff|woff2|eot|ttf|otf)$/, use: ['file-loader'] },
]
},
plugins: [
// cleaning up only 'dist' folder
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
template: 'index.html'
}),
// extract-text-webpack-plugin instance
extractPlugin
],
};
module.exports = config;
Note: I'm testing this on localhost if that makes any difference.
SOLUTION
The problem came from the fact that I wasn't restarting the dev server by running npm run startdev after making some changes.
Include it in the file loader, as you do with images:
{ test: /\.(jpg|png|gif|svg|pdf)$/, use: [ { loader: 'file-loader', options: { name: '[name].[ext]', outputPath: './assets/images/' } } ] },
Note that I have added |pdf after the SVG declaration. Webpack should then process the file as it does with images.
config.module.rules.push({
test: /\.pdf$/,
use: {
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
},
},
});
// vue.config.js configureWebpack
config.module
.rule('pdf')
.test(/\.pdf$/)
.use('pdf')
.loader('file-loader')
.end();
config.module
.rule('pdf')
.test(/\.pdf$/)
.use('file-loader?name=[path][name].[ext]')
.loader('file-loader')
.end();

react production build, assets not loading

I am experiencing annoying problem, when i run my react app in development environment it all works ok, but when i try to build to production, all the links are wrong.
assume this tree:
main_directory
public/
svg/
some_img.svg
src/
components/
some_component.jsx
App.js
index.js
Now in some_component.jsx i am referencing svg file in this way:
src="/public/svg/some_img.svg"
however after building to production this path is untouched and therefore cannot access file anymore, as there i would need it to be changed to this:
src="svg/some_img.svg"
i was playing in the webpack config file, i thought that maybe by setting:
publicPath: "/"
to:
publicPath: "/public/"
would resolve the problem but the only thing it did was error during application start:
CANNOT GET/
my webpack config:
const HtmlWebPackPlugin = require("html-webpack-plugin");
const htmlPlugin = new HtmlWebPackPlugin({
template: "./public/index.html",
filename: "./index.html"
});
module.exports = {
output: {
filename: "main.[hash:8].js",
publicPath: "/"
},
module: {
rules: [
{
test: /\.jsx$/,
exclude: /node_modules/,
loader: "babel-loader?presets[]=react"
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(sass|scss)$/,
use: ["style-loader", "css-loader", "sass-loader", "postcss-loader"]
},
{
test: /\.svg$/,
loader: "svg-sprite-loader"
}
]
},
plugins: [htmlPlugin],
devServer: {
historyApiFallback: {
rewrites: [{ from: /^\/$/, to: "/index.html" }]
}
},
resolve: {
extensions: [".js", ".jsx", ".json"]
}
};
How does one resolve this problem, so for both dev and production paths are unified?
How about importing the svg and then referencing the imported variable:
import someImg from "../../public/svg/some_img.svg"
src={someImg}
this is the solve for the question, config required for to specify path:
module: {
...
rules: [
{
test: /\.(png|jpg|gif|svg|ico)$/,
loader: 'file-loader',
query:{
outputPath: './img/',
name: '[name].[ext]?[hash]'
}
}
...
]
}

Why webpack gives back the mistake ReferenceError: document is not defined?

The text of the mistake
ERROR in ./static/main.sass
Module build failed: ModuleBuildError: Module build failed:ReferenceError: document is not defined
ERROR in ./~/css-loader!./~/resolve-url/resolve-url.js!./~/sass-loader?sourceMap!./static/main.sass
Module build failed: ReferenceError: document is not defined
at Object.resolveUrl (/home/andrew/Test/node_modules/resolve-url/resolve-url.js:21:25)
The webpack.config.js
webpack = require('webpack');
path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
webpackConfig = {
context: __dirname,
entry: {
bundle: './static/app.js',
styles: './static/main.sass'
},
output: {
filename: '[name].js',
path: './static/build'
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devtool: '#cheap-module-source-map',
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: [/node_modules/],
loader: "babel-loader",
query: {
presets: ['es2015', 'react', 'stage-0', 'stage-1']
}
},
{
test: /\.sass$/,
loader: ExtractTextPlugin.extract( 'css-loader!resolve-url!sass-loader?sourceMap')
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
},
{
test: /\.woff2?$|\.ttf$|\.eot$|\.svg$|\.png|\.jpe?g|\.gif$/,
loader: 'file-loader'
}
]
},
plugins: [
new ExtractTextPlugin('styles.css', {
allChunks: true
})
]};
module.exports = webpackConfig;
I thought it may be not having some of the loaders but that's not it.
Besides app.js does not compile in bundle.js too but it doesn't give a mistake. Maybe there is some mistake in entry but I don't know.
You need to include the SCSS file in your app.js (either require or import) and only pass your app.js file as entry for Webpack instead of passing the 2 files as entry.

webpack + babel - react, unexpected token 'import'

I'm trying to make index.js work with es2015.
Before directing me to .babelrc, note that I have added BOTH es2015 and react (to be sure, but there's no react here).
It features
import { default as Logary, Targets, getLogger, build } from 'logary';
And here's .babelrc:
{
"presets": ['es2015', 'react']
}
And webpack.config.js
var webpack = require('webpack'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
path = require('path');
module.exports = {
devtool: 'source-map',
entry: [
'webpack-hot-middleware/client?reload=true',
'./index.js'
],
output: {
path: path.resolve('./dist'),
filename: '[name].js',
publicPath: '/'
},
loaders: [
{ test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{ test: /\.css$/, loader: "style!css" },
{ test: /\.(png|jpg|jpeg|gif|woff)$/, loader: 'url?limit=8192' },
{ test: /\.(otf|eot|ttf)$/, loader: "file?prefix=font/" },
{ test: /\.svg$/, loader: "file" }
],
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.template.html'
}),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
})
],
resolve: {
extensions: ['', '.js']
}
}
Gives error:
ERROR in ./index.js
Module parse failed: /Users/h/logary-js/examples/webpack/index.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import { default as Logary, Targets, getLogger, build } from 'logary';
|
| // once per site/app
Why is it not handling the import-token?
Your webpack.config.js structure is not correct. Webpack doesn't recognize all your loaders. Specifically, you need to put the loaders property inside of a module section like this:
module: {
loaders: [
{ test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{ test: /\.css$/, loader: "style!css" },
{ test: /\.(png|jpg|jpeg|gif|woff)$/, loader: 'url?limit=8192' },
{ test: /\.(otf|eot|ttf)$/, loader: "file?prefix=font/" },
{ test: /\.svg$/, loader: "file" }
],
}

Categories