我正在尝试从 Gulp
转移到 Webpack
。在 Gulp
中,我有一个任务,它将 /static/ 文件夹中的所有文件和文件夹复制到 /build/ 文件夹中。如何使用 Webpack
实现相同的功能?我需要一些插件吗?
我正在尝试从 Gulp
转移到 Webpack
。在 Gulp
中,我有一个任务,它将 /static/ 文件夹中的所有文件和文件夹复制到 /build/ 文件夹中。如何使用 Webpack
实现相同的功能?我需要一些插件吗?
使用 file-loader 模块来要求资源是 webpack 的预期用法(来源)。但是,如果您需要更大的灵活性或更简洁的接口,也可以使用我的 copy-webpack-plugin
直接复制静态文件(npm,Github)。对于您的 static
到 build
示例:
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
context: path.join(__dirname, 'your-app'),
plugins: [
new CopyWebpackPlugin({
patterns: [
{ from: 'static' }
]
})
]
};
兼容性提示:如果您使用的是旧版本的webpack,例如webpack@4.x.x
,请使用copy-webpack-plugin@6.x.x
。否则,请使用最新版本。
不需要像使用gulp一样复制文件,webpack的工作方式不同。Webpack是一个模块打包器,你在文件中引用的所有内容都将被包含在内。你只需要为其指定一个加载器。
因此,如果你编写如下代码:
var myImage = require("./static/myImage.jpg");
Webpack首先会尝试将引用的文件解析为JavaScript(因为这是默认值)。当然,这会失败。这就是为什么您需要为该文件类型指定一个加载器。例如file-或url-loader会获取引用的文件,将其放入webpack的输出文件夹中(在您的情况下应该是build
),并返回该文件的散列URL。
var myImage = require("./static/myImage.jpg");
console.log(myImage); // '/build/12as7f9asfasgasg.jpg'
通常情况下,通过webpack配置来应用加载器:
// webpack.config.js
module.exports = {
...
module: {
loaders: [
{ test: /\.(jpe?g|gif|png|svg|woff|ttf|wav|mp3)$/, loader: "file" }
]
}
};
当然,您需要先安装file-loader才能使其正常工作。
module.exports = {
...
module: {
loaders: [
{ test: /\.(html)$/,
loader: "file?name=[path][name].[ext]&context=./app/static"
}
]
}
};
在你的js文件中:
require.context("./static/", true, /^\.\/.*\.html/);
./static/ 相对于您的 js 文件所在的位置。
您可以对图像或其他内容执行相同操作。上下文是探索的强大方法!!
index.html
放在一个名为 _
(下划线)的子目录中,发生了什么? - krismain.js
中,导入了 static
文件夹中的所有内容:require.context("./static/", true, /^.*/);
- Mario前文提到的copy-webpack-plugin插件具有一个优点,即与其他在此处提到的方法不同,它不会将资源打包进你的捆绑文件中(而且需要你在某个地方“require”或“import”它们)。如果我只想移动一些图像或模板局部,我不想用无用的引用占据我的JavaScript捆绑文件,我只想让这些文件被正确地放置出来。我还没有找到webpack中的其他方法来实现这一点。诚然,这不是webpack最初设计的目的,但它肯定是一个当前的使用案例。(@BreakDS,希望我的回答能解决你的问题 - 只有在你需要它时才是一个好处)
// webpack.config.js
module.exports = {
...
module: {
rules: [
{
test: /\.(jpe?g|gif|png|svg|woff|ttf|wav|mp3)$/,
type: "asset/resource"
}
]
}
};
为了控制文件的输出方式,您可以使用模板路径。
在配置中,您可以在此设置全局模板:
// webpack.config.js
module.exports = {
...
output: {
...
assetModuleFilename: '[path][name].[hash][ext][query]'
}
}
要针对特定一组资源进行覆盖,你可以这样做:
// webpack.config.js
module.exports = {
...
module: {
rules: [
{
test: /\.(jpe?g|gif|png|svg|woff|ttf|wav|mp3)$/,
type: "asset/resource"
generator: {
filename: '[path][name].[hash][ext][query]'
}
}
]
}
};
build/images/img.151cfcfa1bd74779aadb.png
这样的文件名。哈希值可以用于缓存清除等。您应该根据自己的需求进行修改。import myPath from "image.png";
然后使用它,那么Webpack就不会复制它。或者你可能正在使用Webpack开发服务器选项,其中包括一个内存文件系统,不会写入文件系统。如果这些都不能回答你的问题,我建议你提出一个问题,因为我在这里可以列举的信息有限。 - David Archibaldpackage.json
里的脚本中使用cpy-cli
。node
添加到了系统路径中。请将cpy-cli
安装为开发依赖项:
npm install --save-dev cpy-cli
然后创建一对Node.js文件:一个用于复制,另一个用于显示勾号和信息。#!/usr/bin/env node
var shelljs = require('shelljs');
var addCheckMark = require('./helpers/checkmark');
var path = require('path');
var cpy = path.join(__dirname, '../node_modules/cpy-cli/cli.js');
shelljs.exec(cpy + ' /static/* /build/', addCheckMark.bind(null, callback));
function callback() {
process.stdout.write(' Copied /static/* to the /build/ directory\n\n');
}
checkmark.js
var chalk = require('chalk');
/**
* Adds mark check symbol
*/
function addCheckMark(callback) {
process.stdout.write(chalk.green(' ✓'));
callback();
}
module.exports = addCheckMark;
package.json
中添加脚本。假设脚本在<project-root>/scripts/
目录下。...
"scripts": {
"copy": "node scripts/copy.js",
...
运行脚本:
npm run copy
我加载静态图片
和字体
的方式:
module: {
rules: [
....
{
test: /\.(jpe?g|png|gif|svg)$/i,
/* Exclude fonts while working with images, e.g. .svg can be both image or font. */
exclude: path.resolve(__dirname, '../src/assets/fonts'),
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}]
},
{
test: /\.(woff(2)?|ttf|eot|svg|otf)(\?v=\d+\.\d+\.\d+)?$/,
/* Exclude images while working with fonts, e.g. .svg can be both image or font. */
exclude: path.resolve(__dirname, '../src/assets/images'),
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
},
}
]
}
file-loader
才能使其正常工作。[path] [name] .[ext]
,并且提供了足够的灵活性来修改特定环境或用例的内容... file-loader。 - cantuket你可以在package.json文件中编写Bash脚本:
# package.json
{
"name": ...,
"version": ...,
"scripts": {
"build": "NODE_ENV=production npm run webpack && cp -v <this> <that> && echo ok",
...
}
}
"build": "webpack && xcopy images dist\\images\\ /S /Y && xcopy css dist\\css\\ /S /Y"
- SebaGra很可能你应该使用CopyWebpackPlugin,这在kevlened的回答中提到了。另外,对于一些文件类型,比如.html或.json,你也可以使用raw-loader或json-loader。通过npm install -D raw-loader
安装它,然后你只需要将另一个加载器添加到我们的webpack.config.js
文件中即可。
像这样:
{
test: /\.html/,
loader: 'raw'
}
template: require('./nav.html')
module.exports = function(){
return copyTheFiles( inpath, outpath).then( result => {
return { entry: "..." } // Etc etc
} )
}
file-loader
自webpack 5起已被弃用。推荐的方法是使用asset-modules,如此答案所述。 - Liam