Configure Webpack Loaders For a Shared Folder? - google-chrome-extension

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']
}
},

Related

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

React.semantic ui's Icones are not loading with webpack middle ware

I am trying to build a react application using React Semantic.
I am using webpack-dev-server, webpack-hot-middleware and webpack-dev-middleware to automating the tasks.
I installed react semantic ui through npm.
npm install --save semantic-ui-css semantic-ui-react
however, webpack seems to not loading ./node_modules/semantic-ui-css/themes/assets/fonts/ icons and it is not accessabile for the html page.
there is no errors in console, it just does not show the icon.
If I do not import semantic-ui-css in react app and includ in with CDN, it works fine.
App.js
import React from 'react';
import 'semantic-ui-css/semantic.min.css';
import { Container, Icon } from 'semantic-ui-react';
class App extends React.Component{
render(){
return (
<Container fluid>
<h1 id='test'>ReactJs</h1>
<hr/>
<Icon name='search' />
</Container>
)
}
}
export default App;
webpack.config.dev.js
import path from 'path';
import webpack from 'webpack';
export default {
devtool: 'eval-source-map',
entry: [
'webpack-hot-middleware/client',
path.join(__dirname, '/client/index.js')
],
output:{
path: '/',
publicPath: '/',
filename: 'bundle.js'
},
plugins: [
new webpack.NoEmitOnErrorsPlugin,
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin()
],
module:{
loaders: [
{
test: /\.js$/,
include: path.join(__dirname, 'client'),
loaders: ['react-hot-loader', 'babel-loader']
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader','sass-loader'],
},
{
test: /\.scss$/,
exclude: /node_modules/,
loaders: ['raw-loader', 'sass-loader'] // sass-loader not scss-loader
},
{
test: /\.sass$/,
loaders: ["style-loader", "css-loader", "sass-loader"]
},
{
test: /\.svg$/,
loader: 'svg-loader'
},
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
{ test: /\.(ttf|eot|svg|png)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
]
},
resolve:{
extensions: ['.js']
}
}
Is there any loader or package to include icons from semantic ui package?
I am also using SUI-React with webpack. I was having a similar problem, however for me the icon files were 'packed' by webpack, but weren't being loaded correctly. Are you sure that webpack isn't finding them at all?
I eventually found that the source of my issue was the webpack configuration: my output path was a dist subdirectory, from which the index.html loaded bundle.js. This meant that webpack (and file-loader) made the urls relative to that directory. Once I changed my output path to the parent directory, and changed the output file to be dist/bundle.js, everything worked as expected.
My webpack.config.js specifies the entrypoint as yours does (although only one entrypoint, I'm not using webpack-hot-middleware), and my loaders are:
loaders: [
{
test: /\.jsx?/,
include: SRC_DIR,
loader: 'babel'
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'file-loader'
}
]
I'm loading the css using
require("!style-loader!css-loader!semantic-ui-css/semantic.min.css")
in the index file rather than using webpack loaders, however I think that should be equivalent to what you're doing.
Maybe your .css loader rule shouldn't include the sass-loader?
Also, the loader configuration option use seems to have been added in webpack v2, so if you're using webpack v1, that should be loaders as you have for the other rules.
Hope you can figure it out!

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.

Using path.resolve from webpack bundle file

I have a server file that is created from src/server/index.js and bundled to and run from build/server.js. When importing modules everything works, but I am having and issue where a folder can't be found when using path.resolve.
I am doing something like this but once the server file is bundled the following path cannot be found. My guess is because I am not importing it and therefore it is never bundled.
path.resolve(__dirname, 'server/email_templates')
Is there a way to make sure that my application can find this folder after being bundled ?
I have tried to adding resolve object to my webpack config, but that seems to only work for requiring and importing modules, not using the path module. Here's my webpack config object.
entry: {
app: path.join(__dirname, 'src/server/index.js')
},
output: {
path: path.join(__dirname, 'build'),
publicPath: '/assets/',
filename: 'server.js',
libraryTarget: 'commonjs2',
},
target: 'node',
module: {
loaders: [
{
test: /(\.js|\.jsx)$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: [
'react',
'node6',
'stage-0'
]
}
},
serverUrlLoader,
serverStyleLoader,
],
},
Folder Structure
src
|_____server
|-index.js - entry point for bundle
|_____email_templates
build
|_____server.bundle.js

Webpack not bundling .json file in node_modules properly

I am currently building an electron app to deploy on a raspberry pi3 with a react front end. It's using webpack to bundle everything. I am also trying to use the node-raspicam package to interact with the camera module. I have successfully been able to use the node-raspbicam package on it's own outside of this app. But when I try to import it in this application I get the following error
Module not found: Error: Cannot resolve 'file' or 'directory' ../options in /usr/src/app/node_modules/raspicam/lib
# ./~/raspicam/lib/raspicam.js 7:17-38 8:12-33
in raspicam.js it tries to do parameters = require("../options").parameters which is where it is failing.
In the raspicam tree within node_modules options.json exists one directory up from where it is being called.
My thought is webpack is not bundling this json file properly therefore, it cannot be found.
My webpack loaders :
module: {
loaders: [{
test: /\.jsx?$/,
loaders: ['babel-loader'],
exclude: /node_modules/
},
{
test: /\.(jpg|png)$/,
loader: 'file?name=[path][name].[hash].[ext]',
include: path.images
},
{
test: /\.json$/,
loader: 'json-loader'
}]
},
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
libraryTarget: 'commonjs2'
},
resolve: {
extensions: ['', '.js', '.jsx'],
packageMains: ['webpack', 'browser', 'web', 'browserify', ['jam', 'main'], 'main']
},
plugins: [
],
externals: [
// put your node 3rd party libraries which can't be built with webpack here
// (mysql, mongodb, and so on..)
]
I am still fairly new to webpack. What am I missing so that the options.json file in the raspicam node_module gets bundled properly?
Try adding .json to the extensions in the resolve object in the config file. It may work.

Resources