Open dayneh88 opened 3 years ago
Hi,
Having issues trying to get @font-face to work when it's declared in a SASS file. The fonts sit in:
assets/src/fonts
and the SASS file sits in:assets/src/sass/abstracts/_fonts.scss
I'm declaring my @font-face like this:
@font-face { font-family: 'Noigrotesk-Ultra-Light'; src: url('/assets/src/fonts/noigrotesk-100-normal.woff2') format('woff2'), url('/assets/src/fonts/noigrotesk-100-normal.woff') format('woff'); font-weight: 100; }
My console is erroring:
ERROR in ./assets/src/sass/app.scss Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): ModuleParseError: Module parse failed: Unexpected character '' (1:4) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
I've seen things like
url-loader
but I can't find where in the webpack.config.js file where to put it.Any help would be greatly appreciated!
@dayneh88 As I said in another thread, I no longer use this configuration, but I tried to adapt the fonts, so they actually work. I hope this works as the basis for what you are working on. This only changes all the webpack config files, nothing else. :)
/**
* This is the main entry point for Webpack config.
*
* @since 1.0.0
*/
const path = require('path');
// Paths to find our files and provide BrowserSync functionality.
const projectPaths = {
projectDir: __dirname, // Current project directory absolute path.
projectJsPath: path.resolve(__dirname, 'assets/src/js'),
projectScssPath: path.resolve(__dirname, 'assets/src/scss'),
projectImagesPath: path.resolve(__dirname, 'assets/src/img'),
projectFontsPath: path.resolve(__dirname, 'assets/src/fonts'),
projectOutput: path.resolve(__dirname, 'assets/public'),
projectWebpack: path.resolve(__dirname, 'webpack'),
};
// Files to bundle
const projectFiles = {
// BrowserSync settings
browserSync: {
enable: true, // enable or disable browserSync
host: 'localhost',
port: 3600,
mode: 'proxy', // proxy | server
server: { baseDir: ['public'] }, // can be ignored if using proxy
proxy: 'https://rathalos.test/', // ! Change this to your test domain
// BrowserSync will automatically watch for changes to any files connected to our entry,
// including both JS and Sass files. We can use this property to tell BrowserSync to watch
// for other types of files, in this case PHP files, in our project.
files: '**/**/**.php',
reload: true, // Set false to prevent BrowserSync from reloading and let Webpack Dev Server take care of this
// browse to http://localhost:3000/ during development,
https: {
key: '/home/alex/devilbox/ca/certs/main/localhost.key', // ! Add your own key and cert, be sure to expose them if using devilbox
cert: '/home/alex/devilbox/ca/certs/main/localhost.crt',
},
},
// JS configurations for development and production
projectJs: {
eslint: true, // enable or disable eslint | this is only enabled in development env.
filename: 'js/[name].js',
entry: {
frontend: `${projectPaths.projectJsPath}/frontend.js`,
backend: `${projectPaths.projectJsPath}/backend.js`,
},
rules: {
test: /\.m?js$/,
},
},
// CSS configurations for development and production
projectCss: {
postCss: `${projectPaths.projectWebpack}/postcss.config.js`,
stylelint: true, // enable or disable stylelint | this is only enabled in development env.
filename: 'css/[name].css',
use: 'sass', // sass || postcss
// ^ If you want to change from Sass to PostCSS or PostCSS to Sass then you need to change the
// styling files which are being imported in "assets/src/js/frontend.js" and "assets/src/js/backend.js".
// So change "import '../sass/backend.scss'" to "import '../postcss/backend.pcss'" for example
rules: {
sass: {
test: /\.s[ac]ss$/i,
},
postcss: {
test: /\.pcss$/i,
},
},
purgeCss: {
// PurgeCSS is only being activated in production environment
paths: [
// Specify content that should be analyzed by PurgeCSS
`${__dirname}/assets/src/js/**/*`,
`${__dirname}/templates/**/**/*`,
`${__dirname}/template-parts/**/**/*`,
`${__dirname}/blocks/**/**/*`,
`${__dirname}/*.php`,
],
},
},
// Source Maps configurations
projectSourceMaps: {
// Sourcemaps are nice for debugging but takes lots of time to compile,
// so we disable this by default and can be enabled when necessary
enable: false,
env: 'dev', // dev | dev-prod | prod
// ^ Enabled only for development on default, use "prod" to enable only for production
// or "dev-prod" to enable it for both production and development
devtool: 'source-map', // type of sourcemap, see more info here: https://webpack.js.org/configuration/devtool/
// ^ If "source-map" is too slow, then use "cheap-source-map" which struck a good balance between build performance and debuggability.
},
// Images configurations for development and production
projectImages: {
rules: {
test: /\.(jpe?g|png|gif|svg)$/i,
},
// Optimization settings
minimizerOptions: {
// Lossless optimization with custom option
// Feel free to experiment with options for better result for you
// More info here: https://webpack.js.org/plugins/image-minimizer-webpack-plugin/
plugins: [
['gifsicle', { interlaced: true }],
['jpegtran', { progressive: true }],
['optipng', { optimizationLevel: 5 }],
[
'svgo',
{
plugins: [{ removeViewBox: false }],
},
],
],
},
},
};
// Merging the projectFiles & projectPaths objects
const projectOptions = {
...projectPaths,
...projectFiles,
projectConfig: {
// add extra options here
},
};
// Get the development or production setup based
// on the script from package.json
module.exports = (env) => {
if (env.NODE_ENV === 'production') {
return require('./webpack/config.production')(projectOptions);
}
return require('./webpack/config.development')(projectOptions);
};
/**
* This holds the configuration that is being used for both development and production.
* This is being imported and extended in the config.development.js and config.production.js files
*
* @since 1.1.0
*/
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // Extracts the CSS files into public/css
const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); // Synchronising URLs, interactions and code changes across devices
const WebpackBar = require('webpackbar'); // Display elegant progress bar while building or watch
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin'); // To optimize (compress) all images using
const CopyPlugin = require('copy-webpack-plugin'); // For WordPress we need to copy images from src to public to optimize them
module.exports = (projectOptions) => {
/**
* CSS Rules
*/
const cssRules = {
test:
projectOptions.projectCss.use === 'sass'
? projectOptions.projectCss.rules.sass.test
: projectOptions.projectCss.rules.postcss.test,
exclude: /(node_modules|bower_components|vendor)/,
use: [
MiniCssExtractPlugin.loader, // Creates `style` nodes from JS strings
'css-loader', // Translates CSS into CommonJS
{
// loads the PostCSS loader
loader: 'postcss-loader',
options: require(projectOptions.projectCss.postCss)(projectOptions),
},
{
// Compiles Sass to CSS
loader: 'sass-loader',
},
],
};
/**
* JavaScript rules
*/
const jsRules = {
test: projectOptions.projectJs.rules.test,
include: projectOptions.projectJsPath,
exclude: /(node_modules|bower_components|vendor)/,
use: 'babel-loader', // Configurations in "webpack/babel.config.js"
};
/**
* Images rules
*/
const imageRules = {
test: projectOptions.projectImages.rules.test,
type: 'asset/resource',
generator: {
publicPath: '../images/',
filename: '[name][ext]',
emit: false,
},
};
/**
* Font rules
*/
const fontRules = {
test: /\.(eot|ttf|woff|woff2)$/i,
include: projectOptions.projectFontsPath,
exclude: /(node_modules|bower_components|vendor)/,
type: 'asset/resource',
generator: {
publicPath: '../',
filename: 'fonts/[name][ext]',
},
};
/**
* Optimization rules
*/
const optimizations = {};
/**
* Plugins
*/
const plugins = [
new WebpackBar(), // Adds loading bar during builds
// Uncomment this to enable profiler https://github.com/nuxt-contrib/webpackbar#options
// { reporters: [ 'profile' ], profile: true }
new MiniCssExtractPlugin({
// Extracts CSS files
filename: projectOptions.projectCss.filename,
}),
new CopyPlugin({
// Copies images from src to public
patterns: [
{
from: projectOptions.projectImagesPath,
to: `${projectOptions.projectOutput}/images`,
},
],
}),
new ImageMinimizerPlugin({
// Optimizes images
minimizerOptions: projectOptions.projectImages.minimizerOptions,
}),
];
// Add browserSync to plugins if enabled
if (projectOptions.browserSync.enable === true) {
const browserSyncOptions = {
files: projectOptions.browserSync.files,
host: projectOptions.browserSync.host,
port: projectOptions.browserSync.port,
https: projectOptions.browserSync.https,
};
if (projectOptions.browserSync.mode === 'server') {
Object.assign(browserSyncOptions, {
server: projectOptions.browserSync.server,
});
} else {
Object.assign(browserSyncOptions, {
proxy: projectOptions.browserSync.proxy,
});
}
plugins.push(
new BrowserSyncPlugin(browserSyncOptions, {
reload: projectOptions.browserSync.reload,
})
);
}
return {
cssRules,
jsRules,
imageRules,
fontRules,
optimizations,
plugins,
};
};
/**
* Webpack configurations for the development environment
* based on the script from package.json
* Run with: "npm run dev" or "npm run dev:watch"
*
* @since 1.0.0
*/
const ESLintPlugin = require('eslint-webpack-plugin'); // Find and fix problems in your JavaScript code
const StylelintPlugin = require('stylelint-webpack-plugin'); // Helps you avoid errors and enforce conventions in your styles
module.exports = (projectOptions) => {
process.env.NODE_ENV = 'development'; // Set environment level to 'development'
/**
* The base skeleton
*/
const Base = require('./config.base')(projectOptions);
/**
* CSS rules
*/
const cssRules = {
...Base.cssRules,
...{
// add CSS rules for development here
},
};
/**
* JS rules
*/
const jsRules = {
...Base.jsRules,
...{
// add JS rules for development here
},
};
/**
* Image rules
*/
const imageRules = {
...Base.imageRules,
...{
// add image rules for development here
},
};
/**
* font rules
*/
const fontRules = {
...Base.fontRules,
...{
// add image rules for development here
},
};
/**
* Optimizations rules
*/
const optimizations = {
...Base.optimizations,
...{
// add optimizations rules for development here
},
};
/**
* Plugins
*/
const plugins = [
...Base.plugins,
...[
// add plugins for development here
],
];
// Add eslint to plugins if enabled
if (projectOptions.projectJs.eslint === true) {
plugins.push(new ESLintPlugin());
}
// Add stylelint to plugins if enabled
if (projectOptions.projectJs.eslint === true) {
plugins.push(new StylelintPlugin());
}
/** *
* Add sourcemap for development if enabled
*/
const sourceMap = { devtool: false };
if (
projectOptions.projectSourceMaps.enable === true &&
(projectOptions.projectSourceMaps.env === 'dev' ||
projectOptions.projectSourceMaps.env === 'dev-prod')
) {
sourceMap.devtool = projectOptions.projectSourceMaps.devtool;
}
/**
* The configuration that's being returned to Webpack
*/
return {
mode: 'development',
entry: projectOptions.projectJs.entry, // Define the starting point of the application.
output: {
path: projectOptions.projectOutput,
filename: projectOptions.projectJs.filename,
},
devtool: sourceMap.devtool,
optimization: optimizations,
module: { rules: [cssRules, jsRules, imageRules, fontRules] },
plugins,
};
};
/**
* Webpack configurations for the production environment
* based on the script from package.json
* Run with: "npm run prod" or or "npm run prod:watch"
*
* @since 1.0.0
*/
const glob = require('glob-all');
// const PurgecssPlugin = require('purgecss-webpack-plugin'); // A tool to remove unused CSS
module.exports = (projectOptions) => {
process.env.NODE_ENV = 'production'; // Set environment level to 'production'
/**
* The base skeleton
*/
const Base = require('./config.base')(projectOptions);
/**
* CSS rules
*/
const cssRules = {
...Base.cssRules,
...{
// add CSS rules for production here
},
};
/**
* JS rules
*/
const jsRules = {
...Base.jsRules,
...{
// add JS rules for production here
},
};
/**
* Image rules
*/
const imageRules = {
...Base.imageRules,
...{
// add image rules for production here
},
};
/**
* font rules
*/
const fontRules = {
...Base.fontRules,
...{
// add image rules for development here
},
};
/**
* Optimizations rules
*/
const optimizations = {
...Base.optimizations,
...{
splitChunks: {
cacheGroups: {
styles: {
// Configured for PurgeCSS
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true,
},
},
},
// add optimizations rules for production here
},
};
/**
* Plugins
*/
const plugins = [
...Base.plugins,
// ...[
// new PurgecssPlugin({
// // Scans files and removes unused CSS
// paths: glob.sync(projectOptions.projectCss.purgeCss.paths, {
// nodir: true,
// }),
// }),
// // add plugins for production here
// ],
];
/**
* Add sourcemap for production if enabled
*/
const sourceMap = { devtool: false };
if (
projectOptions.projectSourceMaps.enable === true &&
(projectOptions.projectSourceMaps.env === 'prod' ||
projectOptions.projectSourceMaps.env === 'dev-prod')
) {
sourceMap.devtool = projectOptions.projectSourceMaps.devtool;
}
/**
* The configuration that's being returned to Webpack
*/
return {
mode: 'production',
entry: projectOptions.projectJs.entry, // Define the starting point of the application.
output: {
path: projectOptions.projectOutput,
filename: projectOptions.projectJs.filename,
},
devtool: sourceMap.devtool,
optimization: optimizations,
module: { rules: [cssRules, jsRules, imageRules, fontRules] },
plugins,
};
};
@esalexreyes thanks for sending this over. so I've updated all of my webpack configs to match what you sent over. run yarn:dev watch
and still getting this console error:
ERROR in ./assets/src/sass/app.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/css-loader/dist/cjs.js):
Do I need to update the actual @font-face
declaration? Or change the filename of the font files?
Here is a screenshot of my VS: https://ibb.co/m0hyvQJ
We are close! Thanks again for your help mate
@esalexreyes hey mate, just following up on my last question? I'm still having issues. Any help would be greatly appreciated. Thanks
@esalexreyes I managed to get it working. It had to do with my paths in my @font-face. Thanks so much for your help again. Really got me out of a pickle
@dayneh88 Sorry for my late reply! Glad you got it working! :)
Hi,
Having issues trying to get @font-face to work when it's declared in a SASS file. The fonts sit in:
assets/src/fonts
and the SASS file sits in:assets/src/sass/abstracts/_fonts.scss
I'm declaring my @font-face like this:
My console is erroring:
I've seen things like
url-loader
but I can't find where in the webpack.config.js file where to put it.Any help would be greatly appreciated!