我正试着从Gulp转到Webpack。在Gulp中,我有一个任务,它将所有文件和文件夹从/static/文件夹复制到/build/文件夹。如何用Webpack做同样的事情?我需要一些插件吗?
你不需要到处复制东西,webpack的工作方式与gulp不同。Webpack是一个模块捆绑器,你在文件中引用的所有内容都将被包括在内。你只需要为此指定一个加载器。
所以如果你写:
var myImage = require("./static/myImage.jpg");
Webpack将首先尝试将引用的文件解析为JavaScript(因为这是默认的)。当然,这将会失败。这就是为什么您需要为该文件类型指定一个加载器。例如,文件或url加载器获取引用的文件,将其放入webpack的输出文件夹(在您的情况下应该是构建的),并返回该文件的散列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" }
]
}
};
当然,您需要首先安装文件加载器才能使其工作。
使用文件加载器模块要求资产是webpack的使用方式(源代码)。然而,如果你需要更大的灵活性或想要一个更干净的界面,你也可以直接使用我的copy-webpack-plugin (npm, Github)复制静态文件。对于静态构建示例:
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。否则使用最新的。
如果你想复制静态文件,你可以这样使用文件加载器:
对于HTML文件:
在webpack.config.js中:
module.exports = {
...
module: {
loaders: [
{ test: /\.(html)$/,
loader: "file?name=[path][name].[ext]&context=./app/static"
}
]
}
};
在js文件中:
require.context("./static/", true, /^\.\/.*\.html/);
./static/相对于js文件的位置。
你可以对图像或其他东西做同样的事情。 语境是一种强大的探索方法!!
最有可能的是,你应该使用CopyWebpackPlugin,这是在kevlened回答中提到的。另外,对于某些类型的文件,如.html或.json,你也可以使用raw-loader或json-loader。通过npm Install -D raw-loader安装它,然后你只需要在webpack.config.js文件中添加另一个加载器。
如:
{
test: /\.html/,
loader: 'raw'
}
注意:重启webpack-dev-server以使任何配置更改生效。
现在你可以要求html文件使用相对路径,这使得它更容易移动文件夹。
template: require('./nav.html')
以上建议都很好。但是为了直接回答你的问题,我建议在package.json中定义的脚本中使用cpy-cli。
本例期望node位于路径上的某个位置。将cpy-cli安装为开发依赖项:
NPM install——save-dev cpy-cli
然后创建两个nodejs文件。一个用于复制,另一个用于显示复选标记和消息。
copy.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运行拷贝
你可以在package.json中编写bash:
# package.json
{
"name": ...,
"version": ...,
"scripts": {
"build": "NODE_ENV=production npm run webpack && cp -v <this> <that> && echo ok",
...
}
}
我也被困在这里了。Copy-webpack-plugin对我有用。
然而,'copy-webpack-plugin'在我的情况下是不必要的(我后来才知道)。
Webpack忽略根路径 例子
<img src="/images/logo.png'>
因此,在不使用copy-webpack-plugin的情况下实现此功能 在路径中使用“~”
<img src="~images/logo.png'>
'~'告诉webpack将'images'视为一个模块
注意: 您可能必须在中添加images目录的父目录
resolve: {
modules: [
'parent-directory of images',
'node_modules'
]
}
访问https://vuejs-templates.github.io/webpack/static.html
webpack配置文件(在webpack 2中)允许你导出承诺链,只要最后一步返回一个webpack配置对象。参见承诺配置文档。从这里开始:
webpack现在支持从配置文件中返回Promise。这允许在配置文件中进行异步处理。
你可以创建一个简单的递归复制函数来复制你的文件,并且只在触发webpack之后。例如:
module.exports = function(){
return copyTheFiles( inpath, outpath).then( result => {
return { entry: "..." } // Etc etc
} )
}
让我们说你所有的静态资产都在一个文件夹“静态”在根级别,你想复制他们到构建文件夹维护子文件夹的结构,然后 在你的参赛档案中)
//index.js or index.jsx
require.context("!!file?name=[path][name].[ext]&context=./static!../static/", true, /^\.\/.*\.*/);
One advantage that the aforementioned copy-webpack-plugin brings that hasn't been explained before is that all the other methods mentioned here still bundle the resources into your bundle files (and require you to "require" or "import" them somewhere). If I just want to move some images around or some template partials, I don't want to clutter up my javascript bundle file with useless references to them, I just want the files emitted in the right place. I haven't found any other way to do this in webpack. Admittedly it's not what webpack originally was designed for, but it's definitely a current use case. (@BreakDS I hope this answers your question - it's only a benefit if you want it)
我加载静态图像和字体的方式:
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/'
},
}
]
}
不要忘记安装文件加载器来让它工作。
Webpack 5增加了资产模块,这些模块本质上是普通文件加载器的替代品。我复制了以下文档的相关部分:
asset/resource生成一个单独的文件并导出URL。以前可以通过使用文件加载器实现。 asset/inline导出资产的数据URI。以前可以通过使用url加载器实现。 Asset /source导出资产的源代码。以前可以通过使用原始加载器实现。 asset自动在导出数据URI和发出单独的文件之间进行选择。以前可以通过使用url加载器与资产大小限制。
添加一个你可以使你的配置看起来像这样:
// 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的文件名。哈希可以用于缓存破坏等。你应该根据自己的需要进行修改。
在我的例子中,我使用webpack作为wordpress插件来压缩js文件,其中插件文件已经被压缩了,需要跳过这个过程。
optimization: {
minimize: false,
},
externals: {
"jquery": "jQuery",
},
entry: glob.sync('./js/plugin/**.js').reduce(function (obj, el) {
obj[path.parse(el).name] = el;
return obj
}, {}),
output: {
path: path.resolve(__dirname, './js/dist/plugin'),
filename: "[name].js",
clean: true,
},
用于将js文件复制到build文件夹。使用任何其他方法,如文件加载器和复制webpack都会产生问题。
希望它能帮助到一些人。
推荐文章
- 将.NET DateTime转换为JSON
- SameSite警告Chrome 77
- 如何在Webpack配置中创建多个输出路径
- 在ES6 (ECMAScript 6)中是否有一种不带可变变量的循环x次的机制?
- 克隆对象没有引用javascript
- 验证字符串是否为正整数
- 如何获得一个键/值JavaScript对象的键
- 什么时候JavaScript是同步的?
- 如何在Typescript中解析JSON字符串
- Javascript reduce()在对象
- 在angularJS中& vs @和=的区别是什么
- 错误"Uncaught SyntaxError:意外的标记与JSON.parse"
- JavaScript中的querySelector和querySelectorAll vs getElementsByClassName和getElementById
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?