folder/
dist/
assets/
img/
css/
js/
index.html
src/
images/
styles/
js/
twig/
layouts/
partials/
_header.twig
_footer.twig
index.twig
const path = require('path');
module.exports = {
paths: {
base: {
root: path.resolve(__dirname, '..'),
src : path.resolve(__dirname, '../src'),
dist: path.resolve(__dirname, '../dist'),
test: path.resolve(__dirname, '../test')
},
styles: {
src: path.resolve(__dirname, '../src/styles'),
dist: './assets/css/'
},
views: {
src: path.resolve(__dirname, '../src/twig'),
dist: './'
},
scripts: {
src: path.resolve(__dirname, '../src/js'),
dist: './assets/js/'
},
images: {
src: path.resolve(__dirname, '../src/images'),
dist: './assets/img/'
},
fonts: {
src: path.resolve(__dirname, '../src/fonts'),
dist: './assets/fonts/'
}
},
babelLoaderConfig: {
exclude: [
/(node_modules|bower_components)/
]
},
entries: {
'main': '/main.js'
}
}
const HtmlWebpackPlugin = require('html-webpack-plugin');
//config files
const settings = require('./webpack.config.js');
const configureEntries = () => {
let entries = {};
for (const [key, value] of Object.entries(settings.entries)) {
entries[key] = settings.paths.scripts.src + value
}
return entries;
}
// Configure Twig Entries
const configureTwigEntries = (dir) => {
let results = [];
const list = fs.readdirSync(dir);
list.forEach(file => {
file = path.join(dir, file);
const stat = fs.statSync(file);
if (stat && stat.isDirectory() && path.basename(file).indexOf('_') !== 0) {
results = results.concat(configureTwigEntries(file));
} else if (stat && !stat.isDirectory() && path.extname(file) === '.twig' && path.basename(file).indexOf('_') !== 0) {
results.push(file);
}
});
return results;
}
// Configure HtmlWebpackPlugin
const configureHtmlWebpackPlugin = configureTwigEntries(settings.paths.views.src).map(file => {
return new HtmlWebpackPlugin({
template: file,
filename: path.relative(settings.paths.views.src, file).replace('.twig', '.html'),
hash: false
})
});
const configureTwigLoader = () => {
return {
test: /\.twig$/,
exclude: /node_modules/,
use: [
'raw-loader',
{
loader: 'twig-html-loader',
options: {
data: (context) => {
const data = settings.paths.views.src + '/data/data.json';
context.addDependency(data);
return context.fs.readJsonSync(data, { throws: false }) || {};
}
}
},
{
loader: 'extract-loader',
options: {
publicPath: './'
}
},
'html-loader'
]
}
}
/* .... */
const baseConfig = {
context: settings.paths.base.src,
devtool: 'eval-srouce-map',
entry: configureEntries(),
output: {
path: settings.paths.base.dist,
filename: `${settings.paths.scripts.dist}[name].[hash:8].js`
},
resolve: {
extensions: ["*", ".js", ".twig", ".scss"]
},
module: {
rules: [
configureBabelLoader(),
configureFontLoader(),
configureTwigLoader()
]
},
plugins: [
new CleanWebpackPlugin()
].concat(configureHtmlWebpackPlugin)
}
<!-- До -->
<img src="../images/temp/user_ava.png" height="120" width="120" alt="">
<!-- После (в самом index.html) -->
<img src="./assets/img/temp/user_ava.png" height="120" width="120" alt="">
<!-- До -->
<img src="../../images/temp/user_ava.png" height="120" width="120" alt="">
<!-- После (в самом index.html) -->
<img src="../../images/temp/user_ava.png" height="120" width="120" alt="">