I am using webpack for bundling. I am using reactjs and django. I want the static files used by Django and reactjs be separate. I could minified image but the minified images are saved to the folder where the output file is bundled. I want all the minified images to be saved inside frontend -> assets folder. How can i do it so?
The project structure looks like following
app - its a directory where static files are kept for Django. Webpack bundles the react files to app.js and is placed over here because Django template need it to render in its template as <script src='app/bundle/js/app.js'></script>.
frontend - It's a directory where all the react files reside. I want the images to be inside this directory(assets/images/). Images that will be used in reactjs.
How can i do it so?
my webpack right now is configured this way
const path = require("path");
if(!process.env.NODE_ENV) {
process.env.NODE_ENV = 'development';
}
module.exports = {
entry: [
'./src/index.js'
],
output: {
path: path.join("../app/static/build/", "js"),
filename: "app.js",
publicPath: "../app/static/build/"
},
devtoo: 'source-map',
debug: true,
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
},
{test: /\.(jpe?g|png|gif|svg)$/i, loader: "file-loader?name=images/[name].[ext]"},
]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
historyApiFallback: true,
contentBase: './'
}
};
You can specify custom output and public paths by using the outputPath and publicPath query name parameters:
loader: "file-loader?name=[name].[ext]&publicPath=assets/foo/&outputPath=app/images/"
But this feature isn't published to NPM yet. So unfortunatly you'll need to wait while it be published or clone and use this loader from github repo
Related
I have very basic webpack + mini-css-extract-plugin project (you can found it here).
Here is webpack.config.js:
const path = require("path");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
resolve: {
modules: [path.resolve(process.cwd(), 'node_modules')]
},
module: {
rules: [
// file loader allows to copy file to the build folder and form proper url
// usually images are used from css files, see css loader below
{
test: /\.png$/,
exclude: /node_modules/,
use: [
{
loader: 'file-loader',
options: {
name: "_assets/[name].[ext]"
}
}
]
},
// css files are processed to copy any dependent resources like images
// then they copied to the build folder and inserted via link tag
{
test: /\.css$/i,
sideEffects: true,
exclude: /node_modules/,
// for tests we use simplified raw-loader for css files
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// public path has changed so url(...) inside css files use relative pathes
// like: url(../_assets/image.png) instead of absolute urls
publicPath: '../',
}
},
'css-loader'
]
}
]
},
plugins: [
// plugin helps to properly process css files which are imported from the source code
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '_assets/[name].css',
chunkFilename: '_assets/[id].css'
})
],
entry: {
'test': "./src/test"
},
output: {
path: path.resolve(process.cwd(), `public`),
publicPath: '',
filename: '[name].js',
chunkFilename: '_chunks/chunk.[name].js'
}
};
main entry file test.js:
import './css/testCss.css';
console.log('Loaded');
When i run webpack build i got the following output structure:
/
|-test.js
|-_assets/
| |-test.css
When i include this js bundle into html i would expect that test.js bundle will load test.css file dynamically but this is not the case - js bundle works ok, but css file is not loaded at all.
It is only loaded when i modify source of the test.js like so:
import('./css/testCss.css'); // <--------- NOTE: dynamic import here
console.log('Loaded');
in this case after webpack build i got the following output:
/
|-test.js
|-_assets/
| |-0.css
|-_chunks/
| |-chunk.0.js
and when i load this js bundle in html - it loads both chink.0.js and 0.css
MAIN QUESTION: Is dynamic import the only correct way to include css into my js files via mini-css-extract-plugin?
Because in documentation they say yo use normal static import like import "./test.css"
my environement info:
node version: v14.12.0
webpack version: 4.44.1 (also tested on 5.2.0)
mini-css-extract-plugin version 1.1.2
Dynamically loaded Vue components giving me 404 even though the files are compiled correctly into the dist folder by webpack.
Really struggling to see why - but from what i can tell the main.js file is looking for the files relative to the current URL path that it's in.
Vue loader config
module.exports = () => {
return {
test: /\.vue$/,
use: {
loader: 'vue-loader',
}
};
}
webpack.congifg
module.exports = () => ({
entry: [
'./entry.js',
],
devtool: 'source-map',
resolve: {
extensions: ['.js', '.vue'],
modules: [path.resolve(__dirname, './dist'), 'node_modules']
},
module: require('./webpack/module')(),
plugins: require('./webpack/plugins')(),
});
The dist output looks like
when the the main.js file is trying to load the files in (1.js, 1.css) it's trying to get them relative to the url path for example
rather then it trying to get them from localhost/dist/1.js it's trying to pull them in relative to the the url i.e localhost/blog/news/1.js.
I'm building a simple, non-React, html page for webcheck monitoring within a React App. This html page is called specRunner.html. From within specRunner.html I wish to invoke some JavaScript files, but am having difficulty referencing them from my html file.
To be specific, my specRunner.html file can only 'see' JS files if they are stored in the client/dist folder of my directory. I thought I was forming the file path in the tag incorrectly, but I've tested it now and can consistently access a JS file but only if that JS file is in the client/dist folder. Needless to say, I can't put my node_modules file in my client/dist folder.
To be specific I can serve up html files from anywhere in my directory (i.e., my node-express app is not limited to the client/dist file when retrieving files to serve), but my html files can't find js files unless the js file is in the client/dist file.
File structure:
root
--client
----dist
------bundle.js (for the React App)
------index.html (for the React App)
------specRunner.html (<-- my webcheck page I'm working on)
------example.js (<-- example file I'm trying to access from my specRunner.html)
----src
------React stuff
--node_modules (<-- the files I REALLY want to reference from specRunner.html)
--server
--etc.
Here's the Chrome console error when the file is anywhere but the dist folder:
Uncaught SyntaxError: Unexpected token < example.js:1
If I look in the source tab, I can see the content of the example.js file is the html of my server's default endpoint html page for any invalid endpoint calls.
This must be some React issue, even though this endpoint has no React components involved.
Here's my webpack.config:
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const SRC_DIR = path.join(__dirname, '/client/src');
const DIST_DIR = path.join(__dirname, '/client/dist');
module.exports = {
entry: `${SRC_DIR}\\index.js`,
output: {
path: path.resolve(__dirname, 'client/dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.jsx?/,
include: SRC_DIR,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015'],
plugins: ['syntax-dynamic-import'],
},
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader'],
include: SRC_DIR,
},
],
},
resolve: {
extensions: ['.js', '.jsx']
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development'),
},
}),
new ExtractTextPlugin("styles.css"),
],
};
Grateful for any pointers!
I am developing a webapp with NodeJS and webpack. It uses also ReactJS as a dependency. So let's call it simple ui webapp.
In my package.json I reference a package as a dependency which I want to use in the app. This package is not from npm, but it is developed by myself and resides on the same filesystem, local, which totally works fine. I am developing this package, lets call it ui-elements and the webapp in parallel, because I know I have to use the ui-elements in 10 about following webapp-style projects.
Back to the problem: The package gets imported when I npm install, so I have my local package inside the node_modules dir. Good.
This ui-elements-package is also bundled with webpack and contains some React components that use images as background images. Now, when I run ./node_modules/.bin/webpack inside the package folder (while developing the ui-elements package) the file-loader emits the resources into the res/ folder, like I want it to be in the webpack.config.js from the ui-elements package.
But since I want to use the ui-elements package inside my webapp, the resources reside deep inside the node_modules/ dir (node_modules/ui-elements/res).
My question:
How should my webpack.config.js in the webapp project be altered, to get the image resolving by the browser working?
And, am I thinking too complicated? I just want to build and use a package (containing some ui elements with background images), that i can reuse in React webapps. Is there a better approach?
I will paste the extracts of the webpack configs of both projects:
ui-elements
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'index.js',
libraryTarget: 'commonjs2',
path: __dirname
},
module: {
rules: [
{
test: /\.jsx?$/,
include: path.resolve(__dirname, 'src'),
exclude: path.resolve(__dirname, 'node_modules'),
use: [
'babel-loader'
]
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: 'file-loader',
options: {
name: 'res/img/[name].[ext]'
}
}
]
}
]
},
resolve: {
extensions: ['.js', '.jsx'],
modules: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'node_modules')
],
}
};
webapp
webpack.config.js
const path = require('path');
module.exports = {
entry: './index.js',
output: {
filename: 'webapp.bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: path.resolve(__dirname, 'node_modules'),
use: [
'babel-loader'
]
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
},
resolve: {
/*
* this entry makes me use a local working tree of the
* ui-elements package, which makes working easier, i don't
* have to switch projects, rebuild the package and update my
* dependencies in this webapp project
*/
/*
alias: {
"ui-elements": path.resolve(__dirname, 'libDev'),
},
*/
extensions: ['.js', '.jsx'],
modules: [
path.resolve(__dirname, 'src'),
// path.resolve(__dirname, 'libDev'),
path.resolve(__dirname, 'node_modules')
],
}
};
I found this code online to create a webpack for react.. what exactly is happening here? I need something like this to be able to use react right? I'm quite confused.
const path = require('path');
const SRC_DIR = path.resolve(__dirname, 'client');
const BUILD_DIR = path.resolve(__dirname, 'client');
module.exports = {
entry: path.resolve(SRC_DIR, 'client-app.js'),
output: {
filename: 'bundle.js',
path: BUILD_DIR
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: [/node_modules/],
use: [{
loader: 'babel-loader',
options: { presets: ['es2015', 'react'] }
}],
}
]
}
}
Why is it asking me to please add some context? I am trying to add more details so that this question can be posted
The code above does the following:
It resolves the client folder inside your projects folder and saves it to SRC_DIR and BUILD_DIR.
It tells webpack to look for a file named client-app.js in the resolved client folder from step 1.
It tells webpack to output the bundles Javascript into the client folder from step 1 with the file name bundle.js.
It tells webpack to look for any imported or required .js and .jsx files beginning at client-app.js inside your project folder (while excluding files from node_modules unless explicitly imported) and load them into the bundle using the babel-loader with the presets to compile the code from es2015 react to es5.