Make webpack ignore a directory - google-chrome-extension

I'm making a chrome extension that injects content scripts. I don't want Content scripts to be processed by webpack.
My directory structure:
/extension
|-manifest.json
|--scripts
|- background.js
|- content
|-- script1.js
|-- script2.js
|-- ...
Here's my gulp task that calls webpack:
gulp.task('js', (cb) => {
return gulp.src(['source/scripts/**/*.js'])
.pipe(plumber({
errorHandler: function(errors) {
}
}))
.pipe(named())
.pipe(gulpWebpack({
watch: args.watch,
module: {
rules: [
{
enforce: "pre",
test: /\.json$/,
loader: "json-loader"
},
{
enforce: "pre",
test: /\.(gif|jpe?g|png)$/,
loader: "file-loader?name=img/[name].[ext]",
},
{
enforce: "pre",
test: /content\//,
loader: "file-loader?name=content/[name].[ext]",
},
{
test: /\.js$/,
loader: "babel-loader",
exclude: [
/content/
]
}
],
},
}, null, (err, stats) => {
log(`Finished '${colors.cyan('js')}'`, stats.toString({
chunks: false,
colors: true,
cached: false,
children: false
}));
}))
.pipe(gulp.dest(`/scripts`))
});
I want to keep the directory structure in the build directory and not get the files inside content/ to be parsed, ie. to use the file-loader
But they're just getting parsed and my pre rule for content scripts is getting ignored.

Webpack will only process the files which are required by the script which you are compiling. It is not possible to do so as excluding directories with dependencies would break your project.

I've made a separate gulp task to copy those sort of scripts without any processing and excluded that same directory from the gulp task that calls webpack

Related

How to add webfonts and images loaders to webpack

I would like to include webfonts and image loader to my project. I have the following rules in my webpack config:
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: "file-loader",
options: {
outputPath: "./images",
publicPath: "./images",
name: "./[name].[ext]",
},
},
],
},
{
test: /\.(woff|woff2|eot|ttf|svg)$/,
loader: "url-loader",
options: {
outputPath: "./webfonts",
publicPath: "./webfonts",
name: "./[name].[ext]",
},
},
But when I run npm run build it builds the webfonts into the /images folder in the dist folder. How can I prevent webpack from doing this?

How can I make __dirname in a node module refer to the directory that the webpack bundle is generated in?

I am learning Node.
I have a module which I use to read and write files to a directory which I am referencing in my module dataInterface.js as:
const dataInterface = {} as DataInterface;
dataInterface.baseDir = path.join(__dirname, '../.data/');
My directory and file structure is:
/app
/.data
/dist
/src
dataInterface.js
index.js
I use webpack with entry point index.js (which imports dataInterface.js), and the bundle output location is app/dist/index.js.
My webpack.config.js is
module.exports = {
{
entry: './index.ts',
watch: true,
target: 'node',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
},
module: {
rules: [
{ test: /\.tsx?$/, loader: 'ts-loader' },
{
test: /\.js?$/,
exclude: /(node_modules|build)/,
use: [{ loader: 'babel-loader' }],
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
node: {
__dirname: true,
},
};
}
The part
node: {
__dirname: true,
},
is important. When set to true, the reference to __dirname in dataInterface.js is src, so path.join(__dirname, '../.data/'); does resolve to the .data directory in the root folder.
But what I want is for __dirname to refer to dist, which is where the bundle is located. In that case ultimately I want to put .data in dist.
Is this possible and what am I missing in conceptual terms here?

Split assets into bundles in Production with Webpack

I see on almost every production website made in React (or in almost every other framework), that there are splitted css and js bundles inserted into HTML website.
I am using Webpack 4 with this configuration:
module.exports = {
entry: "./src/client/index.js",
output: {
path: outputPath,
filename: "[name].js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}, {
test: /\.css$/,
use: ['style-loader', 'css-loader']
}, {
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000'
}
]
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
devServer: {
port: 3000,
open: true,
proxy: {
'/api': 'http://localhost:8080'
}
},
plugins: [
new CleanWebpackPlugin([outputPath]),
new HtmlWebPackPlugin({
template: "./public/index.html"
})
]
};
But when I build my frontend and serve it by Express, my CSS styles are inlined by <style></style> and also included in main.js file.
How to split CSS,JS and other assets from each other (bundle.css, bundle.js, img/image1.png, etc) instead of inlining CSS and converting images into base64 format?
To create a new file for css, remove style-loader and add https://github.com/webpack-contrib/mini-css-extract-plugin
To do the same with files, remove url-loader and replace it with file-loader

Webpack not including all our js and jsx file, even those in the same directory

We are trying to upgrade our React.js application which uses WebPack to build. In our upgrades we are moving from Webpack 1.0 to 2.0 and I have made the "necessary" changes for the upgrade. It is building, and compiling, however, when I look at the files included, it is a very smaller scale of the files it was including before.
For instance, we have 34 files in our React Flux Actions directory. Some files have .js extension some .jsx. However, of the 34 files, only 1 is showing up in the build. What happened to the other 33. This one has .js extension but there are more .js files in that directory too.
What am I missing?
This is our main config file.
var path = require('path');
var webpack = require('webpack');
var StringReplacePlugin = require("string-replace-webpack-plugin");
var Environment = require('./js/environment');
module.exports = {
entry: [
'./js'
],
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js',
},
plugins: [
new StringReplacePlugin(),
new webpack.LoaderOptionsPlugin({
options: {
tslint: {
emitErrors: true,
failOnHint: true
}
}
})
],
resolve: {
extensions: ['*', '.js', '.jsx'],
modules: [
path.join(__dirname, 'node_modules'),
path.join(__dirname, 'js'),
path.join(__dirname, 'jsx')
]
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot-loader/webpack', 'babel-loader' ]
},
{
test: /js\/constants.js$/,
loader: StringReplacePlugin.replace({
replacements: [{
pattern: /localhost/g,
replacement: Environment.getBackendURL
}]
})
}]
}
};
This is our hot reload local version, I think both files are used, the one above and this one. But I am only doing "npm run build" command right now, then running "npm run local"
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./js/index'
],
output: {
path: path.join(__dirname, 'build-hot'),
filename: 'bundle.js',
publicPath: '/build/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// new webpack.NoErrorsPlugin()
new webpack.LoaderOptionsPlugin({
options: {
tslint: {
emitErrors: true,
failOnHint: true
}
}
})
],
resolve: {
extensions: ['*', '.js', '.jsx'],
modules: [
path.join(__dirname, 'node_modules'),
path.join(__dirname, 'js'),
path.join(__dirname, 'jsx')
]
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot-loader/webpack', 'babel-loader' ]
}]
}
};
Based on Michael's answer below, there is one I did find that is different and feels like could be the reason, but I did not see anything in Webpack2 for pre-loaders. Here is it.
preLoaders: [
{
test: /\.jsx?$/,
loader: "source-map-loader"
}
],
Webpack starts looking at your entry point(s) and only includes files that are being imported, it doesn't just include every file in your project (as described in Concepts - Entry of the official docs).
As your entry point is ./js it will start with ./js/index.js (that's how Node.js and therefore webpack handles importing Folders as Modules), so you're not including every file in that directory. And if you don't import them in ./js/index.js or in its dependencies, the files won't be included at all. Presumably you don't and that's why only this one file is being included in the bundle.
This behaviour hasn't changed from webpack 1 to webpack 2. It's rather surprising that it worked differently with webpack 1, but maybe you changed something in the migration process that you aren't aware of.

Configure Webpack Loaders For a Shared Folder?

Help appreciated!
My question is how do I get webpack to compile assets from a shared folder into the appropriate content script?
I have a Chrome Extension using react-redux-chrome. Their file structure is:
-build
-content
-event
-popup
package.json
gulpfile.babel.js
manifest.json
The gulp file watches for changes and compiles the appropriate javascript, manifest, and html files into build.
Content, event, and popup all have their own webpack configs.
// content/webpack.config.js
const path = require('path');
module.exports = {
entry: [
'./content/src/scripts/index.js'
],
output: {
filename: 'content.js',
path: path.join(__dirname, '../', 'build'),
publicPath: '/'
},
resolve: {
extensions: ['', '.js', '.jsx', '.scss', '.json'],
modulesDirectories: ['node_modules'],
},
module: {
loaders: [
{
test: /\.(jsx|js)?$/,
loader: 'babel',
exclude: /(node_modules)/,
include: path.join(__dirname, 'src'),
query: {
presets: ['es2015', 'react']
}
},
{ test: /\.css$/, loader: "style-loader!css-loader" },
]
}
};
My extension has two content scripts, so my folders look like this...
-build
-content1
-content2
-shared
-event
-popup
package.json
gulpfile.babel.js
manifest.json
Everything works fine until I try to import a React module from the shared folder. The shared folder does not have a webpack config. I get the error: Unexpected token. You may need an appropriate loader to handle this file type.
How do I get webpack to compile assets from the shared folder into the appropriate content script? I tried an alias, but it did not work.
alias: {
shared: path.normalize('../../../../../../shared')
}
I had a brain fart... just needed to make a new loader for the directory. In the content1/webpack.config.js and content2/webpack.config.js files...
{
test: /\.(jsx|js)?$/,
loader: 'babel',
exclude: /(node_modules)/,
include: path.join(__dirname, '../shared'),
query: {
presets: ['es2015', 'react']
}
},

Resources