Related
I am creating a library with UI components to share among my react projects. Components are created with React and with Webpack 5. This is the webpack config file:
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.js',
mode: 'production',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
libraryTarget: 'umd',
library: 'ui-lib',
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.(png|jpg|gif|svg)$/,
type: 'asset/resource',
},
{
test: /.(ttf|otf|eot|woff(2)?)(\?[a-z0-9]+)?$/,
type: 'asset/resource',
generator: {
filename: '[name][ext]',
},
},
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: false,
},
},
{
loader: 'resolve-url-loader',
options: { sourceMap: true, root: path.resolve(__dirname, 'src') },
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[hash].css',
chunkFilename: '[id].[hash].css',
}),
new webpack.ProvidePlugin({
React: 'react',
}),
],
resolve: {
extensions: ['.js', '.jsx', '.scss'],
modules: ['node_modules', path.resolve(__dirname, 'src')],
},
externals: {
react: 'react',
},
};
This is generating a dist/ folder with this content:
Seems everything is fine. The problem is when using this library in a React project, The components seems ok but fonts are not loaded correctly. The console throughs this message:
Failed to decode downloaded font: http://localhost:3000/static/js/GilroySemiBold-webfont.woff2
Fonts are being downloaded but not sure that files are not corrupt.
So, any clue about how can I use the fonts from the library??? Thanks in advance
I am trying to figure out how to set the config up to by default load a different url as the base. Currently it is loading localhost:3000 - I need it to load localhost:3000/market. Client doesn't want the base path to work. For example if this was google, http://google.com wouldn't work and only http://google.com/market would.
I have checked quite a few stacks and this React with webpack was the closest I could find, however I can't use flags for the different environments, so I need it in the config, and I cannot for the life of me figure that out.
This is what I have in my webpack so far:
const appConfig = {
version: pkg.version,
basePath: process.env.BASE_URL,
api: {
baseUrl: `${process.env.BASE_URL}/api`,
},
auth: {
name: "ping",
config: {
clientId: process.env.CLIENT_ID,
authorizationUri: "redacted",
scopes: process.env.SCOPES,
},
},
};
module.exports = {
entry: './src/index.tsx',
output: {
path: path.join(__dirname, 'build/'),
filename: 'marketplace2.js',
globalObject: 'this',
publicPath: '/',
},
mode: nodeEnv,
resolve: {
plugins: [newTsConfigPathsPlugin],
extensions: ['.tsx', '.ts', '.js'],
},
target: 'web',
devServer: {
static: path.join(__dirname, './src'),
open: true,
port: 3000,
},
module: {
rules: [
{
test: /\.(js|jsx|json)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: ['ts-loader'],
},
{
test: /\.(css|scss)$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.(jpg|jpeg|png|gif|mp3|svg|webp|ico)$/,
exclude: /node_modules/,
use: ['file-loader?name=[name].[ext]'],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, './public', 'index.html'),
favicon: path.join(__dirname, './public', 'favicon.ico'),
manifest: path.join(__dirname, './public', 'manifest.json'),
}),
new Dotenv(),
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify(nodeEnv),
"process.env.SERVER": "false",
"process.env.RUN_CONFIG": JSON.stringify(appConfig),
}),
new CopyWebpackPlugin({
patterns: [
{ from: 'public', to: 'public' },
]
}),
],
};
I am working on a React / Typescript project using Webpack (v.4.44.2), along with Vagrant. For routing purposes, I tried to implement a BrowserHistory from react-router-dom. As you can imagine, http://localhost:8000/myUrl didn't work properly on refresh / manual entry at this point. After a bit of research, I tried without success to setup devServer.historyApiFallback and output.publicPath, but nothing works.
My webpack setup looks like this :
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'development',
devtool: 'inline-source-map',
entry: './src/index.tsx',
target: 'web',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist'),
publicPath: '/'
},
resolve: {
extensions: ['.tsx', '.ts', '.js'] // `.js` for external libs (/node_modules/)
},
module: {
rules: [
{ test: /\.tsx?$/i, use: 'ts-loader', exclude: /node_modules/ },
{ test: /\.tsx?$/i, use: 'prettier-loader', enforce: 'pre', exclude: /node_modules/ },
{ test: /\.css?$/i, use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader'], exclude: /node_modules/ },
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'src', 'index.html') }),
new MiniCssExtractPlugin({ filename: 'main.css' })
],
devServer: {
compress: true,
historyApiFallback: {
index: path.join(__dirname, 'dist'),
// index: '/',
},
// historyApiFallback: true,
host: '0.0.0.0',
public: '10.10.10.61',
port: 8000,
watchOptions: {
poll: true
}
}
};
As you can see, I tried several values for historyApiFallback, but I feel like I'm missing something, as I still have the 404 error on refresh. As I'm inside a Vagrant, I wonder if it's an issue regarding the fact that dev bundles are not written to the disk ? or maybe something related to the Vagrant network setup ?
My Vagrantfile is as follows:
Vagrant.configure(2) do |config|
# see https://webpack.js.org/guides/development-vagrant/
config.vm.network :private_network, ip: "10.10.10.61"
config.ssh.insert_key = false
config.vm.define "dev", primary: true do |app|
app.vm.provider "docker" do |d|
d.image = "someImage"
d.name = "#{PROJECT}_dev"
d.has_ssh = true
d.ports = ["0.0.0.0:8000:8000"]
d.env = DOCKER_ENV
end
[...]
end
end
Do you have any idea?
The problem is solved as follow
Vagrant setup :
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'development',
devtool: 'inline-source-map',
entry: './src/index.tsx',
target: 'web',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist'),
publicPath: '/'
},
resolve: {
extensions: ['.tsx', '.ts', '.js'] // `.js` for external libs (/node_modules/)
},
module: {
rules: [
{ test: /\.tsx?$/i, use: 'ts-loader', exclude: /node_modules/ },
{ test: /\.tsx?$/i, use: 'prettier-loader', enforce: 'pre', exclude: /node_modules/ },
{ test: /\.css?$/i, use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader'], exclude: /node_modules/ },
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src', 'index.html'),
filename: path.resolve(__dirname, 'dist', 'index.html')
}),
new MiniCssExtractPlugin({ filename: 'main.css' })
],
devServer: {
contentBase: path.resolve(__dirname, 'dist'),
publicPath: '/',
compress: true,
historyApiFallback: {
disableDotRule: true, // this was what messed me up : in my URL, I have IDs, which for some reason contains dots
index: '/', // same as output.publicPath
},
host: '0.0.0.0',
public: '10.10.10.61',
port: 8000,
watchContentBase: true,
watchOptions: {
poll: true
}
}
};
No tricky stuff related to the filesystem or vagrant. Just an URL "dot" issue that I didn't notice -__-"
Building TS/SASS with Webpack works fine, running this through VSCode Live Server plugin renders the index.html perfectly to the app folder.
Running webpack-dev-server with it looking at the same app folder does not. The page opens but there is a Javascript error Uncaught SyntaxError: Unexpected token '<'
And the page does not render the JS/CSS.
webpack.config.js
// Imports
var path = require("path");
// Plugins
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// Exports
module.exports = {
mode: 'development',
entry: './src/main.ts',
devtool: "inline-source-map",
resolve: {
extensions: [".ts", ".tsx", ".js"]
},
output: {
filename: 'main.min.js',
path: path.resolve(__dirname, 'app')
},
devServer: {
open: 'http://localhost',
port: 80,
publicPath: path.resolve(__dirname, 'app'),
hot: true
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true }
}
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
]
},
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
]
}
tsconfig.json
{
"compilerOptions": {
"sourceMap": true
}
}
main.ts
console.log('Main.ts has loaded')
import './styles/main.scss'
Any help with this would be appreciated, I'm losing my mind lol.
My issue was with syntax in the webpack.config.js file.
I was neglecting to insert a comma at the end of the last entry in every object and array, believing it not to be necessary.
Here is a working config:
// Imports
var path = require("path");
// Plugins
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// Exports
module.exports = {
mode: 'development',
entry: './src/main.ts',
devtool: "inline-source-map",
output: {
filename: 'main.min.js',
path: path.resolve(__dirname, 'app'),
},
devServer: {
open: 'http://localhost',
port: 80,
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true },
}
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
]
},
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader",
]
},
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html",
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css",
}),
]
}
I'm having an issue with React/Redux/Webpack/Router.
Any "sub pages", such as: "/home/test", "users/registration" etc... fail to be loaded - and I get errors loading the "bundle.js" file generated by webpack.
The reason seems to be that the request to fetch the "bundle.js" is with the following url:
for path "/home/test": "/home/bundle.js"
for path "/users/registration": "/users/bundle.js"
Same issue occurs with the loading of "css" files and other resources.
This is my webpack configuration:
const { resolve } = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const OpenBrowserPlugin = require('open-browser-webpack-plugin');
const config = {
devtool: 'cheap-module-eval-source-map',
entry: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
'./main.js',
//'./assets/scss/main.scss',
],
output: {
filename: 'bundle.js',
path: resolve(__dirname, 'dist'),
publicPath: '/',
},
context: resolve(__dirname, 'src'),
devServer: {
hot: true,
contentBase: resolve(__dirname, 'build'),
publicPath: '/',
historyApiFallback: true
},
module: {
rules: [
/* {
enforce: "pre",
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "eslint-loader"
}, */
{
test: /\.(js|jsx)$/,
loaders: [
'babel-loader',
],
exclude: /node_modules/,
},
{
test: /\.(scss|sass)$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
{
loader: 'sass-loader',
query: {
sourceMap: false,
},
},
],
publicPath: '../'
}),
},
{ test: /\.(png|jpg|gif)$/, use: 'url-loader?limit=15000&name=images/[name].[ext]' },
{ test: /\.eot(\?v=\d+.\d+.\d+)?$/, use: 'file-loader?&name=fonts/[name].[ext]' },
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, use: 'url-loader?limit=10000&mimetype=application/font-woff&name=fonts/[name].[ext]' },
{ test: /\.[ot]tf(\?v=\d+.\d+.\d+)?$/, use: 'url-loader?limit=10000&mimetype=application/octet-stream&name=fonts/[name].[ext]' },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, use: 'url-loader?limit=10000&mimetype=image/svg+xml&name=images/[name].[ext]' },
]
},
plugins: [
new webpack.LoaderOptionsPlugin({
test: /\.js$/,
options: {
eslint: {
configFile: resolve(__dirname, '.eslintrc'),
cache: false,
}
},
}),
new webpack.optimize.ModuleConcatenationPlugin(),
new ExtractTextPlugin({ filename: './styles/style.css', disable: true, allChunks: true }),
new CopyWebpackPlugin([{ from: 'vendors', to: 'vendors' }]),
new OpenBrowserPlugin({ url: 'http://localhost:8080' }),
new webpack.HotModuleReplacementPlugin(),
],
};
module.exports = config;
It seems as if it always uses "../bundle.js" to find it for some reason.
Any help would be appreciated :)
Thank you,