I have a Node app which builds React with Webpack and is hosted on Heroku. Whenever I push a newer version to Heroku master, the React files do not update. I have now pushed several newer versions but the React files in webpack:// will not update and remain the originals from when I first deployed the app.
Here is my webpack.config.js file:
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: {
main: `${__dirname}/src/app.js`
},
output: {
path: __dirname,
filename: './public/bundle.js'
},
module: {
loaders: [{
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-2']
},
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/
}]
},
devtool: 'cheap-module-eval-source-map'
};
My package.json includes "heroku-postinstall": "webpack -p -w --config ./webpack.config.js --progress".
I also faced similar issue.
(Just make sure that your webpack config file is correct and does not have any errors while running the webpack build locally)
I modified my post-install script in following way inside my package.json
"scripts": {
"clean": "rimraf public/bundle.*",
"build": "cross-env NODE_ENV=production webpack --config ./webpack.prod.config.js --progress --colors",
"postinstall": "npm run clean && npm run build",
}
When I push my changes to heroku "postinstall" gets called and it perform to task one after another
clean old build files
generate new build
In this way old files gets deleted from cache.
but there are are few dependencies which you need to install
rimraf
npm install --save rimraf
You can choose any other alternative to "rimraf" as well.
Related
I'm faced with a problem with my API in Heroku. I have a Node JS API, built with Typescript and hosted in Heroku. Everything looks correct when I try to execute the local script and build the script, but when I need to run the start script, things don't work.
My configurations are:
Node: v18.12.1
NPM: v8.19.2
I have some scripts to transpile .ts files to .js files with babel
"build": "babel src --extensions \".js,.ts\" --out-dir dist --copy-files",
"dev:server": "ts-node-dev -r tsconfig-paths/register --inspect --transpile-only --ignore-watch node_modules src/shared/infra/http/server.ts",
"start": "node dist/shared/infra/http/server.js"
When I execute dev:server and build script, everything runs with success, but when I run the start script, I receive this error:
enter image description here
I checked some points, like my tsconfig.json and my babel.config, but everything looks correct.
module.exports = {
presets: [
['#babel/preset-env', { targets: { node: 'current' } }],
'#babel/preset-typescript',
],
plugins: [
[
'module-resolver',
{
alias: {
'#modules': './src/modules',
'#config': './src/config',
'#shared': './src/shared',
},
},
],
'babel-plugin-transform-typescript-metadata',
['#babel/plugin-proposal-decorators', { legacy: true }],
['#babel/plugin-proposal-class-properties', { loose: true }],
[
'const-enum',
{
transform: 'removeConst',
},
],
],
};
Because of it, when I deploy API in Heroku, I recive this error:
enter image description here.
I don't have an idea why this occur, because about 1 month ago the API was running perfectly on Heroku production instance.
I appreciate it if anyone can help and give me some tips, about this problem.
What I tried
Check and change my npm and node versions
Check babel confgs
Add "type":"module"in my packages.json
I'm using Vite (vite#3.1.8)
to build Typescript artifacts for an SPA "site" using SolidJS (solid-js#1.6.0).
here's my vite.config.ts
import { defineConfig, resolveBaseUrl } from 'vite'
import solidPlugin from 'vite-plugin-solid'
export default defineConfig({
plugins: [solidPlugin()],
server: {
port: 3000,
},
build: {
target: 'esnext',
outDir: '../htdocs',
rollupOptions: {
input: {
index: "./index.html",
dev: "./dev.html",
test: "./test.ts",
},
output: {
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`
}
},
},
});
Currently, it actually builds 2 html files (index.html and dev.html) and the artifacts needed to run those files. Its great. Couldn't be happier.
I would like to have the transpiler to also kick out test.js so that I can run it to do some sanity checking before deploying to production.
I'm hoping to do vite build, and then run node ../htdocs/assets/test.js (or something similar), and have it block the final deployment if any my sanity tests fail.
however, when I attempt to do this, I get an error when I run test.js, complaining about my use of import statements.
Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
setting my package type to module in package.json doesn't fix it. changing the test file to test.mjs doesnt fix it. I'm not really sure what to try next.
What I really wish it would do is do the whole "import" as part of transpiling, and make one self-contained test.js that just runs. It seems like that is what it does when it builds index.html and dev.html, why wont it do that for my ts file?
That should work. I just tried making a new repo with your vite.config.ts, one-line index.html, dev.html, and test.ts files, and vite, vite-plugin-solid, solid-js installed. In the end I got a ../htdocs/assets/test.js file.
You might also be interested in checking out Vitest which makes testing like this easier to do, and won't accidentally end up in your deployed htdocs.
The best solution I could find was to make a separate config file for building the tests.
import { defineConfig } from 'vite'
import solidPlugin from 'vite-plugin-solid'
export default defineConfig({
plugins: [solidPlugin()],
server: {
port: 3000,
},
build: {
target: 'esnext',
outDir: '../htdocs',
lib: {
entry: "./test-runner.ts",
name: "test-runner",
fileName: "test-runner"
},
rollupOptions: {
},
},
});
and then, update my package.json to make my test script compile and run the output from that alternative vite config.
"scripts": {
"start": "vite",
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"test": "vite build --config vite.config-tests.ts && node ../htdocs/test-runner.umd.js"
},
I don't have much experience configuring Webpack and I am working on a React project and have created an external script that generates a sitemap.xml file. So far so good.
The project is using React 16 and Webpack 4.41, how can I make the sitemap.xml file available to be used in production? When I run npm run build locally I can see the file is not being added to the /public folder, even after I have added the xml rule ( module/rules ) to the webpack.config.js file.
mode: "production",
context: path.resolve(__dirname, "./app"),
entry: {
app: "./js/app.js",
styles: "./scss/main.scss",
},
output: {
filename: "[name].deploy.bundle.js",
path: path.resolve(__dirname, "./public/assets"),
publicPath: "/assets",
},
module: {
rules: [
{ test: /\.html/ },
{ test: /\.xml/ },
]
}
What Am I missing?
Can it be because my file is currently outside the context folder?
The (simplified) project structure is as follows:
project
| sitemap.xml
| node-script-that-creates-sitemap.js
| webpack.config.js
|
└───app/
|
└───public/
I'd appreciate your help.
It turns out the solution didn't have to do with webpack. I managed to solve the issue by copying the file in the build step.
I added these scripts to my package.json file:
"scripts": {
"sitemap-to-build": "npm run generate-sitemap && cp ./sitemap.xml _site/sitemap.xml",
"build": "[other stuff...] && webpack --env.NODE_ENV=production --config webpack.config.js && npm run sitemap-to-build
}
babel-node --experimental-worker app.js
Using this command for starting my project in development mode. Output is:
error: unknown option--experimental-worker'
config .babelrc:
{ "presets": [ ["env", { "targets": { "node": "current" } }], "stage-0", "flow" ], "plugins": [ "transform-decorators-legacy", "transform-flow-strip-types" ] }
This flag is needed to use worker threads. Using babel 6.26
I just ran into this today and replied to the issue on GitHub here. I've pasted my fix below:
I was using Nodemon, and it turns out that there's an option to
include environment variables as NODE_OPTIONS in the nodemon.json
file. This did the trick for me:
{
"watch": ["server"],
"ext": "js",
"env": {
"NODE_OPTIONS": "--experimental-worker"
},
"exec": "babel-node server/server.js"
}
How to integrate Nodemon + worker_threads into a normal NodeJS app:
Set up Nodemon
Add a nodemon.json file to the root folder (example here)
Add this to nodemon.json:
"env": {
"NODE_OPTIONS": "--experimental-worker"
}
If you're setting up Nodemon for the first time, I found
this tutorial very helpful.
The idea is to split your command into two phases:
Phase 1:
babel app.js --out-file app-compiled.js
And phase 2:
node --experimental-worker app-compiled.js
In npm scripts you can then combine the two:
"scripts": {
"pre-build": "babel ./app.js --out-file ./app-compiled.js",
"serve": "yarn pre-build && node --experimental-worker ./app-compiled.js"
}
It not actually for me already. I am refused to use nodemon and run my code with command
node --experimental-worker -r babel-register $NODE_DEBUG_OPTION app.js
It`s help me use exeprimental workers with babel, but with nodemon - not
I'm using VueCLI 2 and build as production. THe build.js is built and compiled into 200KB. When I re-run the server as development, it loaded 3MB. I'm sure the build.js inside dist folder is 200KB. I tried to open index.html but it doesn't work and redirect to root directory on website.
Package.json
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
Webpack
module.exports = { ...
module:{
...
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery',
jQuery: 'jquery'
})
],
devtool: '#eval-source-map'
},
...
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: true
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
return module.context && module.context.indexOf('node_modules') !== -1;
}
})
])
}
HTML
<body>
<script src="/dist/vendor.js"></script>
<script src="/dist/main.js"></script>
</body>
Command
npm run build
npm run dev
npm run build creates a dist directory with a production build of your app.
In order to serve index.html in a browser you need an HTTP server.
For example serve:
npm install -g serve
serve -s dist
The default port is 5000, but can be adjusted using the -l or --listen flags:
serve -s build -l 4000
Docs:
https://create-react-app.dev/docs/deployment#static-server
https://github.com/zeit/serve
https://cli.vuejs.org/guide/deployment.html#previewing-locally
Production build can be run locally by utilizing Vue CLI's tooling simply by running:
vue-cli-service serve --mode production
For convenience, this can be added to package.json scripts:
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"production": "vue-cli-service serve --mode production"
}
Command:
$ npm run production
Very easy with express, and highly extensible/configurable.
Install
npm install -D express
Compose
server.js
// optional: allow environment to specify port
const port = process.env.PORT || 8080
// wire up the module
const express = require('express')
// create server instance
const app = express()
// bind the request to an absolute path or relative to the CWD
app.use(express.static('dist'))
// start the server
app.listen(port, () => console.log(`Listening on port ${port}`))
Execute
node server.js
The Vue CLI tooling (vue-cli-service serve --mode production) still seemed to be serving the development files for me, albeit with process.env.NODE_ENV === 'production'.
To serve the contents of dist, the following worked for me without having to install any extra packages:
npm run build
npx serve dist
With custom port and SSL key/certificate:
npx serve dist -l 8095 --ssl-cert .\cert.pem --ssl-key .\cert-key.pem
You can also put this command into your package.json, e.g.
"scripts": {
"serve": "vue-cli-service serve",
"prod": "npx serve dist",
...
}
Then just do:
npm run prod
Build should be deployed to the server, Hence, I don't think that there is any inbuilt way in vue-cli to run build locally.
To run build locally, we need to configure the server separately and run the build on the server as follow,
1) Install lite server via below command
$ npm install -g lite-server
2) Add below scripts in package.json
"lite": "lite-server –port 10001",
"start": "npm run lite"
3) In root directory create bs-config.js file and add below script
module.exports = {
port: 3000,
server: {
baseDir: './dist'
}
}
4) Lastly, Run it via below command
$ npm run start