如何使用html-webpack-plugin + twig-loader包含图像?

时间:2017-11-19 16:52:44

标签: templates webpack twig html-webpack-plugin

我正在尝试将图像包含在我的树枝模板中,就像简单标记一样,但它不想包含。对于构建,我使用HtmlWebpackPlugin和twig-loader; 但是,如果我使用html-loader和html模板做同样的事情 - 它工作正常。 如何用twig-loader做到这一点?

我的webpack-config:

const path              = require( 'path' );
const HtmlWebpackPlugin = require( 'html-webpack-plugin' );

const PATHS = {
    source: path.join( __dirname, './source' ),
    build:  path.join( __dirname, './build' )
};

module.exports = {
    entry:   `${ PATHS.source }/index.js`,
    output: {
        path:     PATHS.build,
        filename: 'webpack.bundle.js'
    },
    module:  {
        rules: [
            {
                test:   /\.twig/,
                loader: 'twig-loader'
            },
            {
                test: /.*\.(gif|png|jpe?g)$/i,
                use:  [
                    {
                        loader: 'file-loader?name=[name].[ext]'
                    }
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin( {
            filename: 'index.html',
            template: `${PATHS.source}/index.twig`,
        } )
    ],
};

我的树枝模板:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <img src="./chuck-norris.jpg" alt="">
</body>
</html>

我的package.json:

{
  "name": "htmlWebpackPlugin-twigLoader",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack"
  },
  "author": "evisotskiy",
  "license": "ISC",
  "devDependencies": {
    "file-loader": "^0.11.2",
    "html-loader": "^0.5.1",
    "html-webpack-plugin": "^2.30.1",
    "twig-loader": "^0.3.1",
    "webpack": "^3.6.0"
  }
}

我的项目结构:

.
├── webpack.config.js
├── package.json
├── source
|   ├──index.twig
|   ├──index.js (empty)
|   ├──chuck-norris.jpg

当我执行npm run build时,我得到了dir:

├── build
|   ├──index.html
|   ├──webpack.bundle.js

没有chuck-norris.jpg

当我使用html-loader而不是twig-loader和html-template而不是twig-template时 - 图像构建正常。但对于我的项目,我需要使用twig模板。 如何用twig-loader做到这一点?

4 个答案:

答案 0 :(得分:3)

我找到了解决方案。我没有直接将.twig - 文件作为模板传递给HtmlWebpackPlugin,而是将.js - 文件作为模板传递,其中包含.twig文件和图像,并将图像传递给twig-template作为变量。现在项目看起来像这样:

我的webpack-config:

const path              = require( 'path' );
const HtmlWebpackPlugin = require( 'html-webpack-plugin' );

const PATHS = {
    source: path.join( __dirname, './source' ),
    build:  path.join( __dirname, './build' )
};

module.exports = {
    entry:   `${ PATHS.source }/index.js`,
    output: {
        path:     PATHS.build,
        filename: 'webpack.bundle.js'
    },
    module:  {
        rules: [
            {
                test:   /\.twig$/,
                loader: 'twig-loader'
            },
            {
                test: /.*\.(gif|png|jpe?g)$/i,
                use:  [
                    {
                        loader: 'file-loader?name=[name].[ext]'
                    }
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin( {
            filename: 'index.html',
            template: `${PATHS.source}/index.twig.js`,
        } )
    ],
};

我的树枝模板:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <img src="{{ image.src }}" alt="{{ image.alt }}">
</body>
</html>

我的index.twig.js:

const template = require( './index.twig' );

const image = {
    src: require( './chuck-norris.jpg' ),
    alt: "Chuck Norris"
};

module.exports = template( { image } );

我的package.json:

{
  "name": "htmlWebpackPlugin-twigLoader",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack"
  },
  "author": "evisotskiy",
  "license": "ISC",
  "devDependencies": {
    "file-loader": "^0.11.2",
    "html-webpack-plugin": "^2.30.1",
    "twig-loader": "^0.3.1",
    "webpack": "^3.6.0"
  }
}

我的项目结构:

.
├── webpack.config.js
├── package.json
├── source
|   ├──index.twig
|   ├──index.twig.js
|   ├──index.js (empty)
|   ├──chuck-norris.jpg

当我执行npm run build时,我得到了预期的构建项目:

├── build
|   ├──index.html
|   ├──chuck-norris.jpg
|   ├──webpack.bundle.js

答案 1 :(得分:1)

我最近也遇到了同样的问题。但是我无法使用将URL作为参数处理的解决方案。 我已经用extract-loader和html-loader修复了它。 老实说,我不知道它是如何工作的,但是它能工作。

这是任务。  查看带有test: /\.(jpeg|png|svg|jpg|gif)$/i,test: /\.twig$/,

的规则
//region js
task('app:compile', function(){
    return src(path.js.src)
        .pipe(named())
        .pipe(webpack({
            mode: 'development',
            module: {
                rules: [
                    {
                        test: /\.js$/,
                        exclude: /(node_modules|bower_components)/,
                        use: {
                            loader: 'babel-loader',
                            options: {
                                presets: ['@babel/preset-env'],
                                plugins: ['@babel/plugin-proposal-object-rest-spread']
                            }
                        }
                    },
                    {
                        test: /\.(scss|css)$/,
                        exclude: /(node_modules|bower_components)/,
                        use: [
                            {loader: "style-loader"},
                            {loader: "css-loader"},
                            {loader: "sass-loader"},
                        ],
                    },
                    {
                        test: /\.(jpeg|png|svg|jpg|gif)$/i,
                        use: [
                            {
                                loader: 'file-loader',
                                options: {
                                    name: '[name].[ext]',
                                    outputPath: '../images',
                                    publicPath: 'images',
                                }
                            },
                        ],
                    },
                    {
                        test: /\.twig$/,
                        use: [
                            'twig-loader',
                            'extract-loader',
                            {
                                loader:'html-loader',
                            },
                        ],
                    },
                    {
                        test:/\.(woff|woff2|eot|ttf|otf)$/,
                        use: [
                            {
                                loader: 'file-loader',
                                options: {
                                    name: '[name].[ext]',
                                    outputPath: '../fonts',
                                    publicPath: 'fonts',
                                }
                            },
                        ],
                    },
                ],
            },
            devtool: 'source-map',
        }))
        .pipe(dest(path.js.dest));
});
//endregion

希望它可以帮助正在搜索相同问题的人。

答案 2 :(得分:0)

如果有帮助,我可以通过简单地更改处理树枝模板文件的加载器并添加“ html-loader”来解决此问题。

这将是更改:

{
    test:   /\.twig$/,
    loader: 'twig-loader'
}

{
    test: /\.twig$/,
    exclude: /node_modules/,
    use: [
      'html-loader',
      'twig-html-loader'
    ]
}

当然,如果尚未安装,则必须事先安装这些加载器。

npm install twig-html-loader html-loader --save-dev

此后,图像将被处理;)

答案 3 :(得分:0)

我使用Vue CLI在我的高级SPA构建中合并了Twig模板。我遇到的问题与主题入门相同。

我的Twig模板编译良好。但是模板中的图像未复制到构建文件夹。而且,结果输出的HTML文件中的路径也不会转换为Webpack构建和哈希的路径。

同时复制.vue文件中的图像并更新图像路径。

为解决这个问题,我将上述@ s.smsmsm的解决方案核心应用到我的上下文中。谢谢队友。

简而言之:您必须使Webpack能够使用3个加载程序来处理Twig模板。它们是twig-loaderextract-loaderhtml-loader

为此,我指定了vue.config.js

here上有更多说明。简短的版本如下。

// vue.config.js
module.exports = {
    runtimeCompiler: true,
    outputDir: '.dist',
    pages: {
        main: {
            entry: 'src/js/main.js',
            template: 'src/views/pages/index.twig',
            filename: 'index.html'
        }
    },

    // Here is where the fix actually is made.
    chainWebpack: config => {
        config.module
            .rule('twig')
            .test(/\.twig$/)

            .use('twig-loader')
            .loader('twig-loader')
            .end()

            .use('extract-loader')
            .loader('extract-loader')
            .end()
            
            .use('html-loader')
            .loader('html-loader')
            .end();
    }

};

Vue CLI配置参考为here。它的chainWebpack选项用于通过vue.config.js修改相应的Webpack配置部分。如何添加新的加载程序文档为here