Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue loading @font-face #4

Open
dayneh88 opened this issue Jun 15, 2021 · 5 comments
Open

Issue loading @font-face #4

dayneh88 opened this issue Jun 15, 2021 · 5 comments

Comments

@dayneh88
Copy link

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!

@esalexreyes
Copy link

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,
  };
};

@dayneh88
Copy link
Author

@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

@dayneh88
Copy link
Author

@esalexreyes hey mate, just following up on my last question? I'm still having issues. Any help would be greatly appreciated. Thanks

@dayneh88
Copy link
Author

@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

@esalexreyes
Copy link

@dayneh88 Sorry for my late reply! Glad you got it working! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants