Using esbuild with a Rails 7 app, I've been successful in code splitting 2 packages: one with the StimulusJS controllers and another with a ReactJS app. The configuration works fine in development.
When pushed to the CI (GitHub Actions) or pushed directly to Heroku, it times out.
package.json
"scripts": {
"build": "node app/assets/config/esbuild.js",
"build:css": "sass ./app/assets/stylesheets/application.sass.scss ./app/assets/builds/application.css --no-source-map --load-path=node_modules"
}
app/assets/config/esbuild.js
const path = require('path');
require("esbuild").build({
entryPoints: ["stimulus.js","article.js"],
bundle: true,
minify: true,
outdir: path.join(process.cwd(), "app/assets/builds"),
absWorkingDir: path.join(process.cwd(), "app/javascript"),
watch: true,
loader: { '.js': 'jsx' },
publicPath: 'assets',
target: 'es6',
// custom plugins will be inserted is this array
plugins: [],
}).catch(() => process.exit(1));
GitHub Actions
yarn install v1.22.19
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.13s.
yarn run v1.22.19
$ node app/assets/config/esbuild.js
Error: The operation was canceled.
Heroku
Hangs on this step
remote: $ node app/assets/config/esbuild.js
The solution was to remove watch: true
const path = require('path');
require("esbuild").build({
entryPoints: ["stimulus.js","article.js"],
bundle: true,
minify: true,
outdir: path.join(process.cwd(), "app/assets/builds"),
absWorkingDir: path.join(process.cwd(), "app/javascript"),
watch: false, // set to true in dev
loader: { '.js': 'jsx' },
publicPath: 'assets',
target: 'es6',
// custom plugins will be inserted is this array
plugins: [],
}).catch(() => process.exit(1));
Update
For other people who are struggling with this, please see the updated solution and discussion on the project.
const path = require('path');
console.log("NODE_ENV: " + process.env.NODE_ENV);
console.log("CI: " + process.env.CI);
console.log(!(process.env.NODE_ENV === 'production' || process.env.CI));
require("esbuild").build({
entryPoints: ["stimulus.js","article.js"],
bundle: true,
minify: true,
outdir: path.join(process.cwd(), "app/assets/builds"),
absWorkingDir: path.join(process.cwd(), "app/javascript"),
watch: !(process.env.NODE_ENV === 'production' || process.env.CI),
loader: { '.js': 'jsx' },
publicPath: 'assets',
target: 'es6',
// custom plugins will be inserted is this array
plugins: [],
}).catch(() => process.exit(1));
Related
enter image description here
This is my esbuild config:
import * as esbuild from 'esbuild';
const isProduction = process.env.NODE_ENV === 'production';
async function startDevServer(context) {
await context.watch();
let { host, port } = await context.serve({
servedir: './public',
});
}
let ctx = await esbuild.context({
entryPoints: ['index.web.js'],
define: {
'process.env.NODE_ENV': 'production',
'window.IS_PRODUCTION': isProduction ? 'true' : 'false',
},
bundle: true,
minify: isProduction,
sourcemap: !isProduction,
assetNames: 'assets/[name]-[hash]',
format: 'iife',
tsconfig: 'tsconfig.web.json',
loader: {
'.png': 'file',
'.svg': 'file',
'.ttf': 'file',
'.eot': 'file',
'.woff': 'file',
'.woff2': 'file',
'.js': 'tsx',
},
jsx: 'automatic',
treeShaking: true,
resolveExtensions: [
'.web.tsx',
'.web.ts',
'.web.jsx',
'.web.js',
'.tsx',
'.ts',
'.jsx',
'.js',
],
outdir: './public/',
});
!isProduction && startDevServer(ctx);
I tried to install plugins, but it didn't work. When building, I get an error on importing types in package files.
"esbuild-plugin-babel-flow": "^0.0.5",
"esbuild-plugin-flow": "^0.3.2",
I'm having trouble with the Live Reload in Webpack 5 not working. The browser console says:
[webpack-dev-server] Live Reloading enabled.
but it does not reload when I change/save a file. There are no errors in the browser console or terminal.
I'm on Windows 10, using an official Alpine Linux Docker image; my browser is Chrome Version 102.0.5005.63 (Official Build) (64-bit). The project is a fairly simple front end web app.
My package.json dev dependencies:
"devDependencies": {
"html-webpack-plugin": "^5.5.0",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.9.0",
"webpack-webmanifest-loader": "^2.0.2" }
My webpack.config.js file:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
mode: "development",
devtool: "inline-source-map",
target: "web",
devServer: {
static: {
directory: path.join(__dirname, "src"),
},
compress: true,
hot: false,
port: 3000,
liveReload: true,
watchFiles: "./src/*",
},
plugins: [
new HtmlWebpackPlugin({
title: "Title",
template: "src/index.html",
}),
],
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
clean: true,
},
module: {
rules: [
{
test: /\.(png|svg|webp|jpg|jpeg)$/i,
type: "asset/resource",
},
{
test: /\.(json|txt|mp3)$/i,
type: "asset/resource",
},
{
test: /\.webmanifest$/i,
use: "webpack-webmanifest-loader",
type: "asset/resource",
},
],
},
};
When starting the dev server I use the following commands:
npx webpack serve --static assets
My file/folder structure:
New to Webpack in general. Please help!
After sifting through lots of google searches, I finally found a solution in the official webpack documentation: watchOptions.
If watching does not work for you, try out this option. This may help issues with NFS and machines in VirtualBox, WSL, Containers, or Docker. In those cases, use a polling interval and ignore large folders like /node_modules/ to keep CPU usage minimal.
Sooo.... still not sure why it doesn't work with the regular watch option, but polling does work at this time in a docker container.
Here's my webpack.config.js file:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
mode: "development",
devtool: "inline-source-map",
target: "web",
devServer: {
static: ["assets"],
compress: true,
hot: false,
port: 3000,
},
watchOptions: {
ignored: "/node_modules/",
poll: 1000, // Check for changes every second
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
clean: true,
},
plugins: [
new HtmlWebpackPlugin({
title: "Title",
template: "src/index.html",
}),
],
module: {
rules: [
{
test: /\.(png|svg|webp|jpg|jpeg|json|txt|mp3)$/i,
type: "asset/resource",
},
{
test: /\.webmanifest$/i,
use: "webpack-webmanifest-loader",
type: "asset/resource",
},
],
},
};
I use the following command to start it:
npx webpack serve
How do I put a a custom file into the root folder of an electron package when building?
I'm trying to add a file to the root of my electron app when it's packaged. Below is what I currently have. It works to an extent, but then code-signing fails.
export const packagerOptions = {
name: 'app',
platform: 'win32',
arch: 'x64',
dir: path.join(__dirname, '../'),
out: path.join(__dirname, '../dist/packaged'),
ignore: [
/^\/(build|e2e|src)($|\/)/,
/^\/dist\/(installer|packaged)($|\/)/,
/^\/node_modules\/edge\/(build|test)($|\/)/,
/^\/node_modules\/edge\/.+\\.(dll|node)$/,
/^\/node_modules\/electron-edge-js\/(?!.+8\.9\.3).+\.(dll|node)$/,
],
icon: path.join(__dirname, '../assets/win32/app.ico'),
asar: {
unpack: '*.{dll,ico,node}'
},
prune: true,
overwrite: true,
win32metadata: {
CompanyName: 'App Co',
FileDescription: 'App Desktop',
ProductName: 'App Desktop',
InternalName: 'App Desktop'
},
afterExtract: [safeFFMPEG],
afterCopy: [serialHooks([
(buildPath, electronVersion, platform, arch, callback) => {
fs.copyFile(
path.join(__dirname, '../assets/extraResources/MYFILE'),
path.join(buildPath, '..', '..', 'MYFILE'),
err => console.log(err, 'an error occurred'));
}
])],
};
I've tried using:
extraResource: [
path.join(__dirname, '../assets/extraResources/MYFILE')
],
but that puts it in the resources/ folder. I need it to be in the parent folder of resources.
I am trying for the first time to work with angularjs with rails as the back end. I am using webpack-rails gem for the webpack configuration for managing css and other style sheets.
First I made a sample angular + rails app to display a simple text "Hello world". By default the font was in times new roman. Then I added bootstrap to the package.json file as follows.
package.json
{
"name": "shine",
"version": "0.0.1",
"license": "MIT",
"dependencies": {
"stats-webpack-plugin": "^0.4.3",
"webpack": "^1.14.0",
"webpack-dev-server": "^1.16.2",
"css-loader": "^0.23.1",
"file-loader": "^0.9.0",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"bootstrap": "3.3.7"
}
}
Then I ran npm install which generated a folder named node_modules
with all the packages mentioned in the package.json in Project/node_modules path.
And webpack configuration to access access these package files is given in the
webpack.config.js
'use strict';
var path = require('path');
var webpack = require('webpack');
var StatsPlugin = require('stats-webpack-plugin');
// must match config.webpack.dev_server.port
var devServerPort = 3808;
// set NODE_ENV=production on the environment to add asset fingerprints
var production = process.env.NODE_ENV === 'production';
var config = {
entry: {
// Sources are expected to live in $app_root/webpack
'application': './webpack/application.js'
},
output: {
// Build assets directly in to public/webpack/, let webpack know
// that all webpacked assets start with webpack/
// must match config.webpack.output_dir
path: path.join(__dirname, '..', 'public', 'webpack'),
publicPath: '/webpack/',
filename: production ? '[name]-[chunkhash].js' : '[name].js'
},
resolve: {
root: path.join(__dirname, '..', 'webpack')
},
plugins: [
// must match config.webpack.manifest_filename
new StatsPlugin('manifest.json', {
// We only need assetsByChunkName
chunkModules: false,
source: false,
chunks: false,
modules: false,
assets: true
})]
};
if (production) {
config.plugins.push(
new webpack.NoErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({
compressor: { warnings: false },
sourceMap: false
}),
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify('production') }
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin()
);
} else {
config.devServer = {
port: devServerPort,
headers: { 'Access-Control-Allow-Origin': '*' }
};
config.output.publicPath = '//localhost:' + devServerPort + '/webpack/';
// Source maps
config.devtool = 'cheap-module-eval-source-map';
}
module.exports = config;
And in my webpack/application.js I am calling that bootstrap package as follows.
require("bootstrap/dist/css/bootstrap.css");
console.log("Hello world!");
Now when I restart the server and reload the page I don't see any change in the font instead in the console I am getting.
Uncaught Error: Cannot find module "bootstrap/dist/css/bootstrap.css"
at webpackMissingModule
What am I doing wrong here ?
perhaps...
require('boostrap');
if that doesn't work, check to see if the file bootstrap/dist/css/bootstrap.css exists
I try to run our ASP.NET MVC project with webpack2. As the first step, I set up webpack2 with ExtractTextPlugin.
When running webpack watch, I can see that the bundled css file gets updated.
But if I run the project with IISExpress and with webpack watch running, the browser just won't pickup the latest change even though the file has changed.
Verified that if I turn off webpack watch and refresh the browser, then I can see those changes in the browser.
I am running without webpack dev server, here is the webpack.config.js:
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const path = require('path');
module.exports = env => {
return {
entry: {
"main": "./static/entry.js",
"component": path.resolve(__dirname, "../component/static/bundle.js")
},
output: {
path: path.resolve(__dirname, "./static/dist/scripts"),
filename: "[name].index.js"
},
module: {
rules: [
{
test: /\.scss$/,
exclude: /node_modules/,
use:ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{
loader: 'css-loader',
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
includePaths: [
path.resolve(__dirname, './default.css'),
path.resolve(__dirname, './normalize.css')
]
}
}
]
})
},
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ },
{ test: /\.ts$/, loader: 'babel-loader', exclude: /node_modules/ }
]
},
plugins: [
new webpack.ProvidePlugin({
$: path.resolve(__dirname, './node_modules/jquery/src/jquery'),
jQuery: path.resolve(__dirname, './node_modules/jquery/src/jquery'),
moment: path.resolve(__dirname, './node_modules/moment/moment')
}),
new ExtractTextPlugin({
filename: "../style/[name].style.css",
allChunks: true
}),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
compress: {
warnings: false
}
})
]
}
};
The issue is constant and I have no idea what could have happened, help please.
I found the cause of this problem.
Project web.config is caching the client resources, disable output caching fixed the issue.
<caching>
<outputCache enableOutputCache="false" />
</caching>