We’re using a somewhat specialized setup with Bedrock and Sage in docker for the development of a new project. So far everything has worked great, but I just realized that when building, fonts will be placed in a weird way.
yarn build
results in (dockerized, theme has its own container)
Asset Size Chunks Chunk Names
images/icon-hand.svg 3.17 kB [emitted]
/var/www/html/resources/assets/fonts/myfont.woff 49.5 kB [emitted]
scripts/gutenberg.js 1.01 MB 0 [emitted] [big] gutenberg
scripts/main.js 1.27 MB 1 [emitted] [big] main
styles/main.css 490 kB 1 [emitted] [big] main
styles/gutenberg.css 453 kB 0 [emitted] [big] gutenberg
and when running outside of the docker container with my system user
Asset Size Chunks Chunk Names
images/icon-hand.svg 3.17 kB [emitted]
/home/myname/.../src/web/app/themes/name/resources/assets/fonts/myfont.woff 49.5 kB [emitted]
scripts/gutenberg.js 1.01 MB 0 [emitted] [big] gutenberg
scripts/main.js 1.27 MB 1 [emitted] [big] main
styles/main.css 490 kB 1 [emitted] [big] main
styles/gutenberg.css 453 kB 0 [emitted] [big] gutenberg
As you can see:
- images (svg & png) get correctly placed inside images
- styles get correctly placed inside styles
- scripts get correctly placed inside scripts
- fonts get the absolute path prepended, ending up with a path like
app/themes/name/dist//var/www/html/resources/assets/fonts/myfont.woff
webpack.config.js
'use strict' // eslint-disable-line
const webpack = require('webpack')
const merge = require('webpack-merge')
const CleanPlugin = require('clean-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const StyleLintPlugin = require('stylelint-webpack-plugin')
const CopyGlobsPlugin = require('copy-globs-webpack-plugin')
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
const desire = require('./util/desire')
const config = require('./config')
const assetsFilenames = config.enabled.cacheBusting
? config.cacheBusting
: '[name]'
let webpackConfig = {
context: config.paths.assets,
entry: config.entry,
devtool: config.enabled.sourceMaps ? '#source-map' : undefined,
output: {
path: config.paths.dist,
publicPath: config.publicPath,
filename: `scripts/${assetsFilenames}.js`,
},
stats: {
hash: false,
version: false,
timings: false,
children: false,
errors: false,
errorDetails: false,
warnings: false,
chunks: false,
modules: false,
reasons: false,
source: false,
publicPath: false,
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
include: config.paths.assets,
use: 'eslint',
},
{
enforce: 'pre',
test: /\.(js|s?[ca]ss)$/,
include: config.paths.assets,
loader: 'import-glob',
},
{
test: /\.js$/,
exclude: [/node_modules(?)/],
use: [
{ loader: 'cache' },
{ loader: 'buble', options: { objectAssign: 'Object.assign' } },
],
},
{
test: /\.css$/,
include: config.paths.assets,
use: ExtractTextPlugin.extract({
fallback: 'style',
use: [
{ loader: 'cache' },
{
loader: 'css',
options: { sourceMap: config.enabled.sourceMaps },
},
{
loader: 'postcss',
options: {
config: { path: __dirname, ctx: config },
sourceMap: config.enabled.sourceMaps,
},
},
],
}),
},
{
test: /\.scss$/,
include: config.paths.assets,
use: ExtractTextPlugin.extract({
fallback: 'style',
use: [
{ loader: 'cache' },
{
loader: 'css',
options: { sourceMap: config.enabled.sourceMaps },
},
{
loader: 'postcss',
options: {
config: { path: __dirname, ctx: config },
sourceMap: config.enabled.sourceMaps,
},
},
{
loader: 'resolve-url',
options: { sourceMap: config.enabled.sourceMaps },
},
{
loader: 'sass',
options: {
sourceMap: config.enabled.sourceMaps,
sourceComments: true,
includePaths: ['./node_modules'],
},
},
],
}),
},
{
test: /\.(ttf|otf|eot|woff2?|png|jpe?g|gif|svg|ico)$/,
include: config.paths.assets,
loader: 'url',
options: {
limit: 4096,
name: `[path]${assetsFilenames}.[ext]`,
},
},
{
test: /\.(ttf|otf|eot|woff2?|png|jpe?g|gif|svg|ico)$/,
include: /node_modules/,
loader: 'url',
options: {
limit: 4096,
outputPath: 'vendor/',
name: `${config.cacheBusting}.[ext]`,
},
},
],
},
resolve: {
modules: [config.paths.assets, 'node_modules'],
enforceExtension: false,
},
resolveLoader: {
moduleExtensions: ['-loader'],
},
externals: {
jquery: 'jQuery',
},
plugins: [
new CleanPlugin([config.paths.dist], {
root: config.paths.root,
verbose: false,
}),
/**
* It would be nice to switch to copy-webpack-plugin, but
* unfortunately it doesn't provide a reliable way of
* tracking the before/after file names
*/
new CopyGlobsPlugin({
pattern: config.copy,
output: `[path]${assetsFilenames}.[ext]`,
manifest: config.manifest,
}),
new ExtractTextPlugin({
filename: `styles/${assetsFilenames}.css`,
allChunks: true,
disable: config.enabled.watcher,
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: 'popper.js/dist/umd/popper.js',
}),
new webpack.LoaderOptionsPlugin({
minimize: config.enabled.optimize,
debug: config.enabled.watcher,
stats: { colors: true },
}),
new webpack.LoaderOptionsPlugin({
test: /\.s?css$/,
options: {
output: { path: config.paths.dist },
context: config.paths.assets,
},
}),
new webpack.LoaderOptionsPlugin({
test: /\.js$/,
options: {
eslint: { failOnWarning: false, failOnError: true },
},
}),
new StyleLintPlugin({
failOnError: !config.enabled.watcher,
syntax: 'scss',
}),
new FriendlyErrorsWebpackPlugin(),
],
} /** Let's only load dependencies as needed */
/* eslint-disable global-require */ if (config.enabled.optimize) {
webpackConfig = merge(webpackConfig, require('./webpack.config.optimize'))
}
if (config.env.production) {
webpackConfig.plugins.push(new webpack.NoEmitOnErrorsPlugin())
}
if (config.enabled.cacheBusting) {
const WebpackAssetsManifest = require('webpack-assets-manifest')
webpackConfig.plugins.push(
new WebpackAssetsManifest({
output: 'assets.json',
space: 2,
writeToDisk: false,
assets: config.manifest,
replacer: require('./util/assetManifestsFormatter'),
})
)
}
if (config.enabled.watcher) {
webpackConfig.entry = require('./util/addHotMiddleware')(webpackConfig.entry)
webpackConfig = merge(webpackConfig, require('./webpack.config.watch'))
}
/**
* During installation via sage-installer (i.e. composer create-project) some
* presets may generate a preset specific config (webpack.config.preset.js) to
* override some of the default options set here. We use webpack-merge to merge
* them in. If you need to modify Sage's default webpack config, we recommend
* that you modify this file directly, instead of creating your own preset
* file, as there are limitations to using webpack-merge which can hinder your
* ability to change certain options.
*/
module.exports = merge.smartStrategy({
'module.loaders': 'replace',
})(webpackConfig, desire(`${__dirname}/webpack.config.preset`))
config.json
{
"entry": {
"main": ["./scripts/main.js", "./styles/main.scss"],
"customizer": ["./scripts/customizer.js"],
"gutenberg": ["./scripts/gutenberg.js", "./styles/gutenberg.scss"]
},
"publicPath": "/app/themes/name",
"devUrl": "https://myapp-nginx",
"proxyUrl": "https://myapp.local:3000",
"cacheBusting": "[name]_[hash:8]",
"watch": ["app/**/*.php", "config/**/*.php", "resources/views/**/*.php"]
}
I have no idea where to even begin to tackle this problem. The only thing I found related to this are the 2 modules in webpack.config.js - but these should also be applied to the images and there the problem doesn’t exist.
Any ideas?