J'essaie de passer de Gulp
à Webpack
. Dans Gulp
j’ai une tâche qui copie tous les fichiers et dossiers du dossier / static / dans le dossier / build /. Comment faire la même chose avec Webpack
? Ai-je besoin d'un plugin?
Vous n'avez pas besoin de copier les choses, Webpack fonctionne différemment de gulp. Webpack est un bundle de modules et tout ce que vous référencez dans vos fichiers sera inclus. Il vous suffit de spécifier un chargeur pour cela.
Donc si vous écrivez:
var myImage = require("./static/myImage.jpg");
Webpack essaiera d’abord d’analyser le fichier référencé au format JavaScript (car c’est la valeur par défaut). Bien sûr, cela va échouer. C'est pourquoi vous devez spécifier un chargeur pour ce type de fichier. Le fichier - ou rl-loader , par exemple, prend le fichier référencé, le place dans le dossier de sortie de Webpack (qui devrait être build
dans votre cas) et renvoie le URL hachée pour ce fichier.
var myImage = require("./static/myImage.jpg");
console.log(myImage); // '/build/12as7f9asfasgasg.jpg'
Habituellement, les chargeurs sont appliqués via la configuration webpack:
// webpack.config.js
module.exports = {
...
module: {
loaders: [
{ test: /\.(jpe?g|gif|png|svg|woff|ttf|wav|mp3)$/, loader: "file" }
]
}
};
Bien sûr, vous devez d'abord installer le chargeur de fichiers pour que cela fonctionne.
Exiger des ressources à l'aide du module chargeur de fichiers est la façon dont le pack Web doit être utilisé ( source ). Toutefois, si vous avez besoin d'une plus grande flexibilité ou si vous souhaitez une interface plus propre, vous pouvez également copier des fichiers statiques directement à l'aide de mon copy-webpack-plugin
( npm , Github ). Pour votre exemple static
à build
:
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
context: path.join(__dirname, 'your-app'),
plugins: [
new CopyWebpackPlugin([
{ from: 'static' }
])
]
};
Si vous souhaitez copier vos fichiers statiques, vous pouvez utiliser le chargeur de fichiers de cette manière:
pour les fichiers html:
dans webpack.config.js:
module.exports = {
...
module: {
loaders: [
{ test: /\.(html)$/,
loader: "file?name=[path][name].[ext]&context=./app/static"
}
]
}
};
dans votre fichier js:
require.context("./static/", true, /^\.\/.*\.html/);
./static/ est relatif à l’emplacement de votre fichier js.
Vous pouvez faire la même chose avec des images ou autre chose. Le contexte est une méthode puissante à explorer!
Un des avantages apportés par le copy-webpack-plugin susmentionné et qui n'a pas été expliqué auparavant est que toutes les autres méthodes mentionnées ici regroupent toujours les ressources dans vos fichiers bundle (et vous obligent à "exiger" ou "importer" quelque part). Si je veux simplement déplacer des images ou des modèles partiels, je ne veux pas encombrer mon fichier de paquet javascript avec des références inutiles, je veux juste que les fichiers soient émis au bon endroit. Je n'ai pas trouvé d'autre moyen de faire cela dans Webpack. Certes, ce n'est pas pour quoi le webpack a été conçu à l'origine, mais il s'agit sans aucun doute d'un cas d'utilisation courant. (@BreakDS j'espère que cela répond à votre question - ce n'est qu'un avantage si vous le voulez)
Les suggestions ci-dessus sont bonnes. Mais pour essayer de répondre directement à votre question, je suggérerais d'utiliser cpy-cli
dans un script défini dans votre package.json
.
Cet exemple attend de node
quelque part sur votre chemin. Installez cpy-cli
en tant que dépendance de développement:
npm install --save-dev cpy-cli
Ensuite, créez quelques fichiers nodejs. Un pour faire la copie et l'autre pour afficher une coche et un message.
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;
Ajoutez le script dans package.json
. En supposant que les scripts sont dans <project-root>/scripts/
...
"scripts": {
"copy": "node scripts/copy.js",
...
Pour exécuter le script:
npm run copy
Très probablement, vous devriez utiliser CopyWebpackPlugin qui a été mentionné dans la réponse kevlened. Alternativement pour certains types de fichiers tels que . Html ou . Json vous pouvez également utiliser raw-loader ou json-loader. Installez-le via npm install -D raw-loader
et vous n'aurez plus qu'à ajouter un autre chargeur à notre fichier webpack.config.js
.
Comme:
{
test: /\.html/,
loader: 'raw'
}
Remarque: Redémarrez webpack-dev-server pour que les modifications de configuration prennent effet.
Et maintenant, vous pouvez exiger des fichiers HTML en utilisant des chemins relatifs, cela facilite beaucoup le déplacement des dossiers.
template: require('./nav.html')
La façon dont je charge statique images
et fonts
:
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/'
},
}
]
}
N'oubliez pas d'installer file-loader
pour que cela fonctionne.
Le fichier de configuration webpack (dans webpack 2) vous permet d'exporter une chaîne de promesse, à condition que la dernière étape renvoie un objet de configuration webpack. Voir les documents de configuration de promesse . De là:
webpack prend désormais en charge le retour d'une promesse à partir du fichier de configuration. Cela permet de faire un traitement asynchrone dans votre fichier de configuration.
Vous pouvez créer une fonction de copie récursive simple qui copie votre fichier, et uniquement après que cela déclenche webpack. Par exemple.:
module.exports = function(){
return copyTheFiles( inpath, outpath).then( result => {
return { entry: "..." } // Etc etc
} )
}
J'étais coincé ici aussi. copy-webpack-plugin a fonctionné pour moi.
Cependant, 'copie-webpack-plugin' n'était pas nécessaire dans mon cas (j'ai appris plus tard).
webpack ignore les chemins racine
exemple
<img src="/images/logo.png'>
Par conséquent, pour que cela fonctionne sans utiliser 'copy-webpack-plugin', utilisez '~' dans les chemins
<img src="~images/logo.png'>
"~" indique à Webpack de considérer les "images" comme un module
remarque: vous devrez peut-être ajouter le répertoire parent du répertoire images dans
resolve: {
modules: [
'parent-directory of images',
'node_modules'
]
}
Visitez https://vuejs-templates.github.io/webpack/static.html
disons que tous vos actifs statiques sont dans un dossier "statique" au niveau de la racine et que vous voulez les copier dans le dossier de construction en conservant la structure du sous-dossier, puis dans votre fichier d'entrée)
//index.js or index.jsx
require.context("!!file?name=[path][name].[ext]&context=./static!../static/", true, /^\.\/.*\.*/);
Vous pouvez écrire bash dans votre package.json:
# package.json
{
"name": ...,
"version": ...,
"scripts": {
"build": "NODE_ENV=production npm run webpack && cp -v <this> <that> && echo ok",
...
}
}