Broken path when building electron app with webpack and electron-forge - javascript

I have an electron app where I use webpack and build with electron-forge (I think the problem comes from one of these two).
The issue appears when I build the app with electron-forge, no problem during the development process. When the app is built and I start it, no images are displayed and the debugging tool show me that the path it is trying to access is a wrong path.
I build like this:
"main": "./.webpack/main",
"scripts": {
"make": "electron-forge make"
}
When the software is compiled path like this: resources/app/.webpack/renderer/login/images/logo.png
But the image is located here: resources/app/.webpack/renderer/images/logo.png
The login folder wrongly added to the path is there because in my package.json I have this configuration for electron-forge:
"plugins": [
[
"#electron-forge/plugin-webpack",
{
"mainConfig": "./webpack.main.config.js",
"renderer": {
"config": "./webpack.renderer.config.js",
"entryPoints": [
{
"html": "./src/front/views/window.html",
"js": "./src/front/scripts/login.ts",
"name": "login",
"preload": {
"js": "./src/preload.ts"
}
},
// other entrypoints
]
}
}
]
]
And we can see that the name of one entrypoint is "login" which is the first page of my app and which is the page the image is supposed to be on. But in development no login folder is created however when I build, login is added to the path of image that are supposed to be on the login page.
I have tried to install electron-webpack and do some changes to the webpack config files. For now, in the file webpack.renderer.config.js I have this:
const rules = require('./webpack.rules');
// other rules
rules.push({
test: /\.(png|svg|jpg|gif)$/,
include: [
path.resolve(__dirname, "src/front/images"),
],
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}
});
module.export = {
module: {
rules
}
// other things
}

Related

Webpack configuration to allow import

I am creating a basic structure where the controller.js would need some Views to be imported from view.js and hence this is what I am using in the controller.js
import View from './View'
However there was an issue with the bundler with webpack and I ended up visiting this page
https://webpack.js.org/loaders/imports-loader/
and below is webpack.config.js.. I've added the lines at the end to the RULES as metioned in the documentation
I ran npm install npm install imports-loader --save-dev
// SOURCE OF TUTORIAL
// https://www.youtube.com/watch?v=MpGLUVbqoYQ&t=1205s
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
mode: "development",
devtool: false,
entry: {
main: "./src/js/controller.js",
model: "./src/js/model.js",
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/main.html",
}),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader", // injects STYLES into DOM
"css-loader", // turns CSS into commonjs
"sass-loader", // turns SASS into CSS
],
},
{
test: /\.html$/,
use: ["html-loader"],
},
{
test: /\.(png|gif|svg|jpe?g)$/,
type: "asset/resource",
},
{
test: require.resolve("./path/to/example.js"),
loader: "imports-loader",
options: {
type: "module",
imports: "default lib myName",
},
},
],
},
};
The last section of the rule is what I have added.. it's a basic copy paste without really understanding what it does and it didn't work.. I am obviously doing somethibg wrong but I could not figure it out even after reading the section at the link above..
Could someone explain how the last section should be configured so that I am able to use import? I've recently created this webpack configuration based on a youtube tutorial so my knowledge on webpack is very basic..
Any help would be appreciated.

babel-plugin-module-resolver adding extra ../ to path

While I am aware that Babel is capable of transpiling TypeScript itself, I've had enough weird issues I'd like to first transpile TypeScript->JS and then run Babel on that.
I've got my tsconfig.json files working as expected. When I compile my TypeScript (from ./src folder relative to babel.config.json's path), it outputs to a ./build folder. I have Babel set to take what's in the ./build folder and output to the ./dist folder.
The output of TSC shows import {bar} from 'foo' and import {thing} from 'foo/util', as expected. But Babel's output looks like ../../../libfoo/libfoo.js when it should be ../../libfoo/libfoo.js
No matter what I try with root/cwd, I can't seem to get that extra ../ to disappear. I've managed to make it go away a couple times, but then I rebuild without changing the babel config, and it comes back.
My babel.config.json currently looks like this:
{
"presets": [
["#babel/preset-env", {"targets": {
"node": true,
"electron": "80"
}}],
["#babel/preset-typescript", { "onlyRemoveTypeImports": true }]
],
"plugins": [
["babel-plugin-module-resolver", {
"alias": {
"^foo/(.+)": "./libfoo/\\1.js",
"^foo$": "./libfoo/libfoo.js"
}
}],
["#babel/plugin-transform-modules-umd"],
["#babel/plugin-transform-typescript", {
"allowNamespaces": true,
"allowDeclareFields": true,
"onlyRemoveTypeImports": true
}],
["#babel/plugin-proposal-pipeline-operator", { "proposal": "fsharp" }],
"#babel/plugin-proposal-nullish-coalescing-operator",
"#babel/plugin-proposal-optional-chaining",
"#babel/plugin-proposal-do-expressions",
"#babel/plugin-proposal-logical-assignment-operators",
"#babel/plugin-proposal-partial-application",
["#babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }],
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-throw-expressions",
"#babel/plugin-proposal-export-default-from",
"#babel/plugin-proposal-export-namespace-from",
"#babel/plugin-proposal-function-bind"
],
"sourceMaps": true
}
Well, I found a solution that doesn't really fix the problem but makes it works.
My files structure is something like this:
|-dist
|-src
|-db
|-connect
|-index.ts
|-index.ts
|-.babelrc
When babel compiles the code, the import of db/connect in src/index.ts, go from this:
import ... from "db/connect"
to this:
var _connect = require("../db/connect");
To resolve this, I simply add /dist to the paths in .babelrc
before:
[
"module-resolver",
{
"root": ["./"], # or ["src"] or "src" or ["./src"] or "./src" or any way you can imagine
"alias": {
"db": "./db",
}
}
}
]
after:
[
"module-resolver",
{
"alias": {
"db": "./dist/db",
}
}
}
]
And the import is now:
var _connect = require("../dist/db/connect");
As you said, the root doesn't affect the require path, so I just removed it.
This doesn't fix the problem, but makes it work.
Hope it helps, good luck! :)

Build Angular Application for production

Hello I am having great difficulty building my angular application for production.
I am running the 'ng build --prod' command however when i open the 'dist' folder i don't see all my components there. Is there something else i have to change or configure? When opening the 'dist' folder i see some components.
angular.json
{
"$schema":"./node_modules/#angular/cli/lib/config/schema.json",
"version":1,
"newProjectRoot":"projects",
"projects":{
"app":{
"projectType":"application",
"schematics":{
"#schematics/angular:component":{
"style":"scss"
}
},
"root":"",
"sourceRoot":"src",
"prefix":"app",
"architect":{
"build":{
"builder":"#angular-devkit/build-angular:browser",
"options":{
"outputPath":"dist/app",
"index":"src/index.html",
"main":"src/main.ts",
"polyfills":"src/polyfills.ts",
"tsConfig":"tsconfig.app.json",
"aot":false,
"assets":[
"src/favicon.ico",
"src/assets",
"src/images"
],
"styles":[
"src/styles.scss"
],
"scripts":[
]
},
"configurations":{
"production":{
"fileReplacements":[
{
"replace":"src/environments/environment.ts",
"with":"src/environments/environment.prod.ts"
}
],
"optimization":true,
"outputHashing":"all",
"sourceMap":false,
"extractCss":true,
"namedChunks":false,
"aot":true,
"extractLicenses":true,
"vendorChunk":false,
"buildOptimizer":true,
"budgets":[
{
"type":"initial",
"maximumWarning":"2mb",
"maximumError":"5mb"
},
{
"type":"anyComponentStyle",
"maximumWarning":"6kb",
"maximumError":"10kb"
}
]
}
}
},
"serve":{
"builder":"#angular-devkit/build-angular:dev-server",
"options":{
"browserTarget":"app:build"
},
"configurations":{
"production":{
"browserTarget":"app:build:production"
}
}
},
"extract-i18n":{
"builder":"#angular-devkit/build-angular:extract-i18n",
"options":{
"browserTarget":"app:build"
}
},
"test":{
"builder":"#angular-devkit/build-angular:karma",
"options":{
"main":"src/test.ts",
"polyfills":"src/polyfills.ts",
"tsConfig":"tsconfig.spec.json",
"karmaConfig":"karma.conf.js",
"assets":[
"src/favicon.ico",
"src/assets"
],
"styles":[
"src/styles.scss"
],
"scripts":[
]
}
},
"lint":{
"builder":"#angular-devkit/build-angular:tslint",
"options":{
"tsConfig":[
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude":[
"**/node_modules/**"
]
}
},
"e2e":{
"builder":"#angular-devkit/build-angular:protractor",
"options":{
"protractorConfig":"e2e/protractor.conf.js",
"devServerTarget":"app:serve"
},
"configurations":{
"production":{
"devServerTarget":"app:serve:production"
}
}
}
}
}
},
"defaultProject":"app"
}
ts.config.json
{
"compileOnSave":false,
"compilerOptions":{
"baseUrl":"./",
"outDir":"./dist/out-tsc",
"sourceMap":true,
"declaration":false,
"downlevelIteration":true,
"experimentalDecorators":true,
"module":"esnext",
"moduleResolution":"node",
"importHelpers":true,
"target":"es2015",
"typeRoots":[
"node_modules/#types"
],
"lib":[
"es2018",
"dom"
]
},
"angularCompilerOptions":{
"fullTemplateTypeCheck":true,
"strictInjectionParameters":true
}
}
Output when running a new build:
I now get this error when run in the console locally:
Failed to load resource: net::ERR_FILE_NOT_FOUND
index.html:1 Access to script at 'file:///C:/polyfills-es2015.0fe6949bc5ff4b784062.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
Yes this is how it should look, you have the index.html, the favicon.ico, a css file and a bunch of .js file. Their names are weird because Angular "compile" them this way. If you visit your website it'll be working
When you run ng build --prod, then Angular will do some actions (rough description):
Run module bundler(e.g. WebPack).
WebPack will see should all modules and will create a dependency tree. Then WebPack based on dependency tree will inlcude only used components in final file(bundle). It is called tree shaking.
Then uglify happens. Uglify means all unnecessary whitespaces will be deleted, variable names will be shortened
So this is a reason why you don't see any components and why you cannot debug bundled files.

ReactJS linting (eslint) and transpiling (babel) error on shared code using monorepo (Lerna + Yarn Workspaces)

I´m building a monorepo using yarn workspaces, lerna and 2 different projects:
ux - a React component library built using create-react-app
auth - a React application that uses ux library built using create-react-app and then ejected (the ejection was done to try to solve the current linting and transpiling error).
My monorepo setup is:
project
|-------- node_modules
|-------- lerna.json
|-------- package.json
|-------- packages
|----------- auth
|------- node_modules
|------- src
|------- packages.json
|----------- ux
|------- node_modules
|------- src
|------- packages.json
lerna.json:
{
"lerna": "2.9.0",
"npmClient": "yarn",
"useWorkspaces": true,
"packages": [
"packages/*"
],
"version": "3.0.0"
}
Lerna root package.json:
{
"name": "myorganization",
"version": "3.0.0",
"license": "UNLICENSED",
"workspaces": ["packages/*"],
"private": true,
"scripts": {
"clean": "lerna clean -f --yes && rm -rf node_modules",
"reset": "yarn run clean && yarn",
"auth": "cd packages/auth && yarn start"
},
"devDependencies": {
"lerna": "^2.9.0"
}
}
ux package.json: (ux was not ejected)
{
"name": "#myorganization/ux",
"version": "3.0.0",
"author": "Me",
"private": true,
"license": "UNLICENSED",
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "2.0.0-next.9754a231"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": {
"development": [
"last 2 chrome versions",
"last 2 firefox versions",
"last 2 edge versions"
],
"production": [
">1%",
"last 4 versions",
"Firefox ESR",
"not ie < 11"
]
},
"devDependencies": {
"eslint": "^4.19.0",
"eslint-plugin-react": "^7.7.0"
}
}
auth package.json:
{
"name": "#myorganization/auth",
"version": "3.0.0",
"private": true,
"author": "Me",
"license": "UNLICENSED",
"dependencies": {
"#myorganization/ux": "^3.0.0",
"#babel/core": "7.0.0-beta.38",
"#babel/runtime": "7.0.0-beta.38",
"autoprefixer": "7.2.5",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "8.2.1",
"babel-jest": "22.1.0",
"babel-loader": "8.0.0-beta.0",
"babel-preset-react-app": "4.0.0-next.9754a231",
"case-sensitive-paths-webpack-plugin": "2.1.1",
"chalk": "2.3.0",
"css-loader": "0.28.9",
"dotenv": "4.0.0",
"dotenv-expand": "4.0.1",
"eslint-config-react-app": "3.0.0-next.9754a231",
"eslint-loader": "1.9.0",
"eslint-plugin-flowtype": "2.41.0",
"eslint-plugin-import": "2.8.0",
"eslint-plugin-jsx-a11y": "6.0.3",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.6",
"fs-extra": "5.0.0",
"html-webpack-plugin": "2.30.1",
"identity-obj-proxy": "3.0.0",
"jest": "22.1.2",
"object-assign": "4.1.1",
"postcss-flexbugs-fixes": "3.2.0",
"postcss-loader": "2.0.10",
"promise": "8.0.1",
"raf": "3.4.0",
"react": "^16.2.0",
"react-dev-utils": "6.0.0-next.9754a231",
"react-dom": "^16.2.0",
"react-router-dom": "^4.2.2",
"style-loader": "0.19.1",
"svgr": "1.6.0",
"sw-precache-webpack-plugin": "0.11.4",
"thread-loader": "1.1.2",
"uglifyjs-webpack-plugin": "1.1.6",
"url-loader": "0.6.2",
"webpack": "3.10.0",
"webpack-dev-server": "2.11.0",
"webpack-manifest-plugin": "1.3.2",
"whatwg-fetch": "2.0.3"
},
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js --env=jsdom"
},
"browserslist": {
"development": [
"last 2 chrome versions",
"last 2 firefox versions",
"last 2 edge versions"
],
"production": [
">1%",
"last 4 versions",
"Firefox ESR",
"not ie < 11"
]
},
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx,mjs}"
],
"setupFiles": [
"<rootDir>/config/polyfills.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,mjs}",
"<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}"
],
"testEnvironment": "node",
"testURL": "http://localhost",
"transform": {
"^.+\\.(js|jsx|mjs)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|mjs|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"'[/\\\\]node_modules[/\\\\](?!' + paths.allLernaModules.join('|') + ').*\\.(js|jsx|mjs)$'",
"^.+\\.module\\.css$"
],
"moduleNameMapper": {
"^react-native$": "react-native-web",
"^.+\\.module\\.css$": "identity-obj-proxy"
},
"moduleFileExtensions": [
"web.js",
"mjs",
"js",
"json",
"web.jsx",
"jsx",
"node"
]
},
"babel": {
"presets": [
"react-app"
]
},
"eslintConfig": {
"extends": "react-app"
},
"devDependencies": {
"eslint": "^4.19.0",
"eslint-plugin-react": "^7.7.0"
}
}
Then I´ve changed the create-react-app created config/paths to grab the referenced packages:
"use strict";
const path = require("path");
const fs = require("fs");
const url = require("url");
// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebookincubator/create-react-app/issues/637
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
const envPublicUrl = process.env.PUBLIC_URL;
function ensureSlash(path, needsSlash) {
const hasSlash = path.endsWith("/");
if (hasSlash && !needsSlash) {
return path.substr(path, path.length - 1);
} else if (!hasSlash && needsSlash) {
return `${path}/`;
} else {
return path;
}
}
const getPublicUrl = appPackageJson =>
envPublicUrl || require(appPackageJson).homepage;
// We use `PUBLIC_URL` environment variable or "homepage" field to infer
// "public path" at which the app is served.
// Webpack needs to know it to put the right <script> hrefs into HTML even in
// single-page apps that may serve index.html for nested URLs like /todos/42.
// We can't use a relative path in HTML because we don't want to load something
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
function getServedPath(appPackageJson) {
const publicUrl = getPublicUrl(appPackageJson);
const servedUrl =
envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : "/");
return ensureSlash(servedUrl, true);
}
// config after eject: we're in ./config/
module.exports = {
dotenv: resolveApp(".env"),
appPath: resolveApp("."),
appBuild: resolveApp("build"),
appPublic: resolveApp("public"),
appHtml: resolveApp("public/index.html"),
appIndexJs: resolveApp("src/index.js"),
appPackageJson: resolveApp("package.json"),
appSrc: resolveApp("src"),
yarnLockFile: resolveApp("yarn.lock"),
testsSetup: resolveApp("src/setupTests.js"),
appNodeModules: resolveApp("node_modules"),
publicUrl: getPublicUrl(resolveApp("package.json")),
servedPath: getServedPath(resolveApp("package.json"))
};
module.exports.lernaRoot = path
.resolve(resolveApp("."), "../")
.endsWith("packages")
? path.resolve(resolveApp("."), "../../")
: resolveApp(".");
module.exports.appLernaModules = [];
module.exports.appLernaNodeModules = path.join(
module.exports.lernaRoot,
"node_modules"
);
fs.readdirSync(module.exports.appLernaNodeModules).forEach(folderName => {
if (folderName === "react-scripts") return;
if (folderName.substr(0, 1) === ".") return;
let fullName = path.join(module.exports.appLernaNodeModules, folderName);
if (folderName.substr(0, 1) === "#" && fs.lstatSync(fullName).isDirectory()) {
fs.readdirSync(fullName).forEach(subFolderName => {
let subFullName = path.join(fullName, subFolderName);
if (fs.lstatSync(subFullName).isSymbolicLink()) {
let src = fs.realpathSync(subFullName);
module.exports.appLernaModules.push(src);
}
});
}
if (fs.lstatSync(fullName).isSymbolicLink()) {
module.exports.appLernaModules.push(fs.realpathSync(fullName));
}
});
And changed the create-react-app original webpack.config.dev to:
"use strict";
const autoprefixer = require("autoprefixer");
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin");
const InterpolateHtmlPlugin = require("react-dev-utils/InterpolateHtmlPlugin");
const WatchMissingNodeModulesPlugin = require("react-dev-utils/WatchMissingNodeModulesPlugin");
const eslintFormatter = require("react-dev-utils/eslintFormatter");
const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin");
const getClientEnvironment = require("./env");
const paths = require("./paths");
// Webpack uses `publicPath` to determine where the app is being served from.
// In development, we always serve from the root. This makes config easier.
const publicPath = "/";
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
const publicUrl = "";
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);
// Options for PostCSS as we reference these options twice
// Adds vendor prefixing based on your specified browser support in
// package.json
const postCSSLoaderOptions = {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: "postcss",
plugins: () => [
require("postcss-flexbugs-fixes"),
autoprefixer({
flexbox: "no-2009"
})
]
};
console.log(paths.appLernaModules.concat(paths.appSrc));
// This is the development configuration.
// It is focused on developer experience and fast rebuilds.
// The production configuration is different and lives in a separate file.
module.exports = {
// You may want 'eval' instead if you prefer to see the compiled output in DevTools.
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.
devtool: "cheap-module-source-map",
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
// The first two entry points enable "hot" CSS and auto-refreshes for JS.
entry: [
// We ship a few polyfills by default:
require.resolve("./polyfills"),
// Include an alternative client for WebpackDevServer. A client's job is to
// connect to WebpackDevServer by a socket and get notified about changes.
// When you save a file, the client will either apply hot updates (in case
// of CSS changes), or refresh the page (in case of JS changes). When you
// make a syntax error, this client will display a syntax error overlay.
// Note: instead of the default WebpackDevServer client, we use a custom one
// to bring better experience for Create React App users. You can replace
// the line below with these two lines if you prefer the stock client:
// require.resolve('webpack-dev-server/client') + '?/',
// require.resolve('webpack/hot/dev-server'),
require.resolve("react-dev-utils/webpackHotDevClient"),
// Finally, this is your app's code:
paths.appIndexJs
// We include the app code last so that if there is a runtime error during
// initialization, it doesn't blow up the WebpackDevServer client, and
// changing JS code would still trigger a refresh.
],
output: {
// Add /* filename */ comments to generated require()s in the output.
pathinfo: true,
// This does not produce a real file. It's just the virtual path that is
// served by WebpackDevServer in development. This is the JS bundle
// containing code from all our entry points, and the Webpack runtime.
filename: "static/js/bundle.js",
// There are also additional JS chunk files if you use code splitting.
chunkFilename: "static/js/[name].chunk.js",
// This is the URL that app is served from. We use "/" in development.
publicPath: publicPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, "/")
},
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebookincubator/create-react-app/issues/253
modules: ["node_modules", paths.appNodeModules].concat(
// It is guaranteed to exist because we tweak it in `env.js`
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
// `web` extension prefixes have been added for better support
// for React Native Web.
extensions: [".web.js", ".mjs", ".js", ".json", ".web.jsx", ".jsx"],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
"react-native": "react-native-web"
},
plugins: [
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson])
]
},
module: {
strictExportPresence: true,
rules: [
// Disable require.ensure as it's not a standard language feature.
{ parser: { requireEnsure: false } },
// First, run the linter.
// It's important to do this before Babel processes the JS.
{
test: /\.(js|jsx|mjs)$/,
enforce: "pre",
use: [
{
options: {
formatter: eslintFormatter,
eslintPath: require.resolve("eslint")
},
loader: require.resolve("eslint-loader")
}
],
include: paths.appLernaModules.concat(paths.appSrc)
},
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
oneOf: [
// "url" loader works like "file" loader except that it embeds assets
// smaller than specified limit in bytes as data URLs to avoid requests.
// A missing `test` is equivalent to a match.
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve("url-loader"),
options: {
limit: 10000,
name: "static/media/[name].[hash:8].[ext]"
}
},
// Process application JS with Babel.
// The preset includes JSX, Flow, and some ESnext features.
{
test: /\.(js|jsx|mjs)$/,
include: paths.appLernaModules.concat(paths.appSrc),
use: [
// This loader parallelizes code compilation, it is optional but
// improves compile time on larger projects
require.resolve("thread-loader"),
{
loader: require.resolve("babel-loader"),
options: {
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
highlightCode: true
}
}
]
},
// Process any JS outside of the app with Babel.
// Unlike the application JS, we only compile the standard ES features.
{
test: /\.js$/,
use: [
// This loader parallelizes code compilation, it is optional but
// improves compile time on larger projects
require.resolve("thread-loader"),
{
loader: require.resolve("babel-loader"),
options: {
babelrc: false,
compact: false,
presets: [
require.resolve("babel-preset-react-app/dependencies")
],
cacheDirectory: true,
highlightCode: true
}
}
]
},
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
// "style" loader turns CSS into JS modules that inject <style> tags.
// In production, we use a plugin to extract that CSS to a file, but
// in development "style" loader enables hot editing of CSS.
// By default we support CSS Modules with the extension .module.css
{
test: /\.css$/,
exclude: /\.module\.css$/,
use: [
require.resolve("style-loader"),
{
loader: require.resolve("css-loader"),
options: {
importLoaders: 1
}
},
{
loader: require.resolve("postcss-loader"),
options: postCSSLoaderOptions
}
]
},
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
// using the extension .module.css
{
test: /\.module\.css$/,
use: [
require.resolve("style-loader"),
{
loader: require.resolve("css-loader"),
options: {
importLoaders: 1,
modules: true,
localIdentName: "[path]__[name]___[local]"
}
},
{
loader: require.resolve("postcss-loader"),
options: postCSSLoaderOptions
}
]
},
// Allows you to use two kinds of imports for SVG:
// import logoUrl from './logo.svg'; gives you the URL.
// import { ReactComponent as Logo } from './logo.svg'; gives you a component.
{
test: /\.svg$/,
use: [
{
loader: require.resolve("babel-loader"),
options: {
cacheDirectory: true
}
},
require.resolve("svgr/webpack"),
{
loader: require.resolve("file-loader"),
options: {
name: "static/media/[name].[hash:8].[ext]"
}
}
]
},
// "file" loader makes sure those assets get served by WebpackDevServer.
// When you `import` an asset, you get its (virtual) filename.
// In production, they would get copied to the `build` folder.
// This loader doesn't use a "test" so it will catch all modules
// that fall through the other loaders.
{
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
loader: require.resolve("file-loader"),
options: {
name: "static/media/[name].[hash:8].[ext]"
}
}
]
}
// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
]
},
plugins: [
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In development, this will be an empty string.
new InterpolateHtmlPlugin(env.raw),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml
}),
// Add module names to factory functions so they appear in browser profiler.
new webpack.NamedModulesPlugin(),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
new webpack.DefinePlugin(env.stringified),
// This is necessary to emit hot updates (currently CSS only):
new webpack.HotModuleReplacementPlugin(),
// Watcher doesn't work well if you mistype casing in a path so we use
// a plugin that prints an error when you attempt to do this.
// See https://github.com/facebookincubator/create-react-app/issues/240
new CaseSensitivePathsPlugin(),
// If you require a missing module and then `npm install` it, you still have
// to restart the development server for Webpack to discover it. This plugin
// makes the discovery automatic so you don't have to restart.
// See https://github.com/facebookincubator/create-react-app/issues/186
new WatchMissingNodeModulesPlugin(paths.appNodeModules),
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how Webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
],
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node: {
dgram: "empty",
fs: "empty",
net: "empty",
tls: "empty",
child_process: "empty"
},
// Turn off performance hints during development because we don't do any
// splitting or minification in interest of speed. These warnings become
// cumbersome.
performance: {
hints: false
}
};
OBS: Repair the console.log() command in the code above to show what is being loaded.
Running, I´m getting the following result:
$ npm start
> #myorganization/auth#3.0.0 start D:\project\packages\auth
> node scripts/start.js
[ 'D:\\project\\packages\\auth',
'D:\\project\\packages\\ux',
'D:\\project\\packages\\auth\\src' ]
Starting the development server...
Failed to compile.
../ux/src/atoms/index.js
Module build failed: Error: No ESLint configuration found.
Commenting the eslint step in webpack.config.dev, I´m getting:
$ npm start
> #myorganization/auth#3.0.0 start D:\project\packages\auth
> node scripts/start.js
[ 'D:\\project\\packages\\auth',
'D:\\project\\packages\\ux',
'D:\\project\\packages\\auth\\src' ]
Starting the development server...
Failed to compile.
../ux/src/atoms/ActivityItem/ActivityItem.js
Syntax error: D:\project\packages\ux\src\atoms\ActivityItem\ActivityItem.js: Support for the experimental syntax 'classProperties' isn't currently enabled (34:20):
32 | class ActivityItem extends Component {
33 |
> 34 | static propTypes = {
| ^
35 | showHeader: PropTypes.bool,
36 | timestamp: PropTypes.number,
37 | username: PropTypes.string,
Add #babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the 'plugins' section of your Babel config to enable transformation.
In short, the shared code is not being either transpiled or linted, and that breaks the whole project. The whole project was done using ES6.
As of react-scripts 2.0 they removed support for monorepos (https://github.com/facebook/create-react-app/issues/1333). However if you scroll to the bottom of the issues page you will see a link to react-workspaces. I've not tried it, but it looks promising. (https://github.com/react-workspaces/react-workspaces-playground)

how to test if babel works and my plugins are executed

I'm using Next.js for Server Side Rendering of React application (with styled-components) and have issue with Babel plugins I'm using to show name of the components I'm using in code.
This is my .babelrc file:
{
"env": {
"development": {
"presets": ["next/babel"],
"plugins": [
[
"babel-plugin-styled-components",
{
"ssr": true,
"displayName": true,
"preprocess": false
}
]
]
},
"production": {
"presets": "next/babel",
"plugins": [
[
"babel-plugin-styled-components",
{
"displayName": false,
"ssr": true
}
]
]
},
"test": {
"presets": [
[
"env",
{
"modules": "commonjs"
}
],
"next/babel"
]
}
}
}
When I'm running cross-env NODE_ENV=development concurrently "tsc --watch" next
I'm getting these lines - meaning .babelrc is used during copilation:
[1] > Using external babel configuration
[1] > Location: "...../.babelrc"
[1] > Using "webpack" config function defined in next.config.js.
But once I go to dev tools and see some styled-component I can see this: class="sc-iyvyFf gGaJAt" but on my code I have this definition:
const Title = styled.div`
font-size: 40px;
line-height: 1.13;
`
As it seems from documentation example - I should get something like ... <button class="Button-asdf123 asdf123" /> instead of just <button class="asdf123" />. But I don't.
After going deeper I found this issue ( https://github.com/styled-components/styled-components/issues/1103#issuecomment-324302997 ) based on errors I get in browser console that said:
It seems that only the server code is being transpiled and not the client code 😉
So Question: How to test if babel works correctly and .babelrc is being used in all places?
P.S. In my case those classes that I've got on client side had this prefix sc- meaning in my head styled-components. So I was not sure if the plugin from .babelrc works at all or it works, but I haven't set any special property in declaration of styled-components thus get this general prefix sc-
UPDATE Here is my custom next.conf.js I'm using
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const { ANALYZE } = process.env
const path = require('path')
module.exports = {
exportPathMap: function() {
return {
'/': { page: '/' }
}
},
webpack: function(config) {
if (ANALYZE) {
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'server',
analyzerPort: 8888,
openAnalyzer: true
})
)
}
config.resolve.alias = {
'styled-components': path.resolve('./node_modules/styled-components/')
}
return config
}
}
Looks like no one has unfortunately answered this before;
What you're seeing probably comes down to this little piece of code you posted: tsc --watch
If you execute TypeScript transpilation before Babel and leave it up to TypeScript to transpile to ES5, it'll transpile all tagged template literals, not giving our plugin anything to hook onto.
Since you're already using next.js you won't need to set up your Babel pipeline from scratch. Rather you only need to disable this type of transpilation in TypeScript.
I'd suggest you to set target inside your tsconfig.json to ESNext so that it leaves everything up to Babel.
https://www.typescriptlang.org/docs/handbook/compiler-options.html (See "--target")

Categories

Resources