Here is my webpack config:
{
entry: './public/static/js/app/app.js',
output: {
path: './public/static/dist/js/',
filename: 'app-compiled.js',
pathinfo: true
},
module: {
loaders: [
{
test: /public\/static.*\.js$/,
loader: 'babel-loader',
},
{
test: /\.html$/,
loader: 'raw'
},
],
},
plugins: [
new webpack.dependencies.LabeledModulesPlugin()
],
resolveLoader: {
alias: {
'text': 'raw',
},
root: ['./public/static/js/app']
},
resolve: {
extensions: ['', '.js'],
root: [
path.resolve('./public/static/js/app'),
],
modulesDirectories: ['node_modules'],
alias: {
'backbone': path.resolve('./public/static/js/lib/backbone.js'),
'backbone.relational': path.resolve('./public/static/js/lib/backbone-relational.js'),
'backbone.wreqr': path.resolve('./public/static/js/lib/backbone.wreqr.min.js'),
'marionette': path.resolve('./public/static/js/lib/marionette.js'),
'text': path.resolve('./public/static/js/lib/text.js'),
'smoke': path.resolve('./public/static/js/lib/smoke.js'),
'_': path.resolve('./public/static/js/lib/underscore.js'),
'underscore.inflection': path.resolve('./public/static/js/lib/underscore.inflection.js'),
'chosen': path.resolve('./public/static/js/lib/chosen.js'),
'spin': path.resolve('./public/static/js/lib/spin.min.js'),
'uuid': path.resolve('./public/static/js/lib/uuid-v4.min.js'),
'ladda': path.resolve('./public/static/js/lib/ladda.min.js'),
'jquery': path.resolve('./public/static/js/lib/jquery.js')
}
},
debug: true,
devtool: 'sourcemap',
};
The problem I am seeing in the browser is root is undefined. The compiled code that reads that is var previousBackbone = root.Backbone;
You should not need Babel to transpile node nodules such as Backbone. We want Webpack to use the pre-built javascript inside a given npm package. In not excluding the transpiling of node_modules, I expect Babel is making some optimisations to Backbone that it shouldn't. To exclude node_modules, add an exclude property to your babel loader e.g.
{
test: /public\/static.*\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
}
Related
So, I need to prefix my react components classNames so it doesn't conflict with global classes.
And no, I can't use CSS modules because of how my yarn workspaces are built
So, if I have a button class I would like it to become my_app-button
<button className="button">Hello StackOverflow</button>
to
<button className="my-app_button">Hello StackOverflow</button>
PostCSS does that for me in the CSS part, but on the React Side I wasn't able to find a solution
All of my components use typescript
I've tried using a webpack loader to do the job, and it did! But only on my Storybook server, when I used it with my separate webpack config it didn't work
The only error that is given to me is invariant 85
This is my Webpack Config, alongside the webpack loader and the babel-loader
import { Configuration, ProgressPlugin } from 'webpack'
const config: Configuration = {
mode: 'production',
entry: './src/index.ts',
target: 'node',
output: {
filename: '[name].js',
path: __dirname + '/dist',
publicPath: '',
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['#babel/preset-react', '#babel/preset-env', 'minify'],
},
},
],
},
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-react',
'#babel/preset-env',
'#babel/preset-typescript',
'minify',
],
},
},
],
},
{
test: /\.tsx$/,
exclude: /node_modules/,
use: [
{
loader: 'react-classname-prefix-loader?prefix=giffy_css',
},
],
},
{
test: /\.(png|jpe?g|gif)$/,
exclude: /node_modules/,
use: [{ loader: 'file-loader' }],
},
],
},
plugins: [new ProgressPlugin()],
}
export default config
and just in case you need it, this is my Storybook webpack configuration
webpackFinal: async (config, { configType }) => {
config.module.rules.push({
test: /\.tsx$/,
exclude: /node_modules/,
use: [
{
loader: 'react-classname-prefix-loader?prefix=giffy_css',
},
],
})
// console.log(config.module.rules[0].use[0].options.overrides[0])
return config
}
i have also tried first compiling my components with babel and then using webpack
i tried searching for an equivalent webpack loader in babel, but could not find it
Recently i had to create a new project in react using typescript / webpack. I have included the package "sass-loader" which has a dependency of chalk (1.1.3).
When I try to npm start, the console shows this error:
Uncaught ReferenceError: process is not defined
at Object../node_modules/chalk/index.js (main.js:62661)
at __webpack_require__ (main.js:228732)
at fn (main.js:228970)
at Object../node_modules/#babel/highlight/lib/index.js (main.js:403)
at __webpack_require__ (main.js:228732)
at fn (main.js:228970)
at Object../node_modules/#babel/code-frame/lib/index.js (main.js:19)
at __webpack_require__ (main.js:228732)
at fn (main.js:228970)
at Object../node_modules/parse-json/index.js (main.js:120631)
I don't know if this could be a problem with this package or maybe is my webpack configuration... I'm new in webpack.
Here is my webpack conf:
{
mode: "development",
output: {
publicPath: "/",
},
entry: "./src/index.tsx",
module: {
rules: [
{
test: /\.(ts|js)x?$/i,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
"#babel/preset-env",
"#babel/preset-react",
"#babel/preset-typescript",
],
},
},
},
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
{
loader: 'css-loader',
options: {
modules: {
localIdentName: 'styles_[local]_[hash:base64:5]'
}
},
},
// Compiles Sass to CSS
"sass-loader",
],
},
{
test: /\.css$/i,
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
{
loader: 'css-loader',
options: {
modules: {
localIdentName: 'styles_[local]_[hash:base64:5]'
}
},
}
],
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js", ".jsx"],
alias: {
'#': '/src',
},
},
plugins: [
new Dotenv(),
new HtmlWebpackPlugin({
template: "public/index.html",
}),
new webpack.HotModuleReplacementPlugin(),
new ForkTsCheckerWebpackPlugin({
async: false,
}),
new ESLintPlugin({
extensions: ["js", "jsx", "ts", "tsx"],
})
],
devtool: "inline-source-map",
devServer: {
contentBase: path.join(__dirname, "build"),
historyApiFallback: true,
port: 4000,
open: false,
hot: true,
stats: 'errors-only'
},
}
Thanks in advance.
I really appreciate some help here, in this case, I would Like to separate my vendor.js and my main.js at the final build operation.
I've tried that before to loop through in my package.json devDependency for separate my third party libraries and put it into vendor.js, it is working correctly but it produces vendor.js that is unnecessary in building process since my third library already is in my main.js
here is my weppack.config.js
var config = {
devtool: 'eval-source-map',
cache: true,
entry: {
main: path.join(__dirname, "app", "App.js"),
},
output: {
path: path.join(__dirname, 'scripts', 'js'),
filename: '[name].js',
chunkFilename: '[name].js',
sourceMapFilename: '[file].map',
publicPath: '/scripts/js/'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['es2015', { modules: false }],
'react',
],
plugins: [
'syntax-dynamic-import',
'transform-object-rest-spread',
'transform-class-properties',
'transform-object-assign',
],
}
},
},
],
},
resolve: {
extensions: ['.js', '.jsx' ,'.css', '.ts'],
alias: {
'react-loadable': path.resolve(__dirname, 'app/app.js'),
},
},
};
Due to this answer
in his webpack.config.js (Version 1,2,3) file, He has
function isExternal(module) {
var context = module.context;
if (typeof context !== 'string') {
return false;
}
return context.indexOf('node_modules') !== -1;
}
in his plugins array
plugins: [
new CommonsChunkPlugin({
name: 'vendors',
minChunks: function(module) {
return isExternal(module);
}
}),
// Other plugins
]
This should solve your problem like mine.
I'm integrating typescript in my React app which has significant amount of code. I've some app level HOCs which I apply on React Components as :
import React from 'react';
import HOC1 from 'app/hocs/hoc1';
import compose from 'recompose/compose;
class MyComponent from React.Component {
...component stuff...
}
export default compose(HOC1())(MyComponent);
But now I've added typescript in my application, whenever I'm importing
import HOC1 from 'app/hocs/hoc1';
it says
TS2307: Cannot find module 'app/hocs/hoc1'.
I don't want to add type definitions to all my HOCs. What is the solution and why I'm getting this error?
[EDIT] I'm using baseUrl in tsconfig as well. My folder structure is
/Project/configs/tsconfig
/Project/src/app/hocs
In tsconfig, I've given baseUrl as ../src through this documentation.
Another Edit
And my webpack config looks like :
{
test: /\.(t|j)sx?$/,
loader: 'happypack/loader?id=jsx-without-proptypes',
include: [
path.resolve(__dirname),
path.resolve(__dirname, '../src'),
],
},
The whole webpack config looks something like
const config = {
context: path.resolve(__dirname, '../src'),
mode: NODE_ENV,
optimization: {
splitChunks: false,
nodeEnv: NODE_ENV,
minimize: false,
},
node: {
net: 'empty',
},
output: {
path: path.resolve(__dirname, '../build/public/assets'),
publicPath: '/assets/',
sourcePrefix: ' ',
pathinfo: DEBUG, //https://webpack.js.org/configuration/output/#output-pathinfo
},
module: {
noParse: [/html2canvas/],
rules: [
{
test: /\.tsx?$/,
enforce: 'pre',
use: { loader: 'awesome-typescript-loader' },
},
...shimLoaders,
...selectiveModulesLoader,
{
test: /\.(t|j)sx?$/,
loader: 'happypack/loader?id=jsx-without-proptypes',
include: [
path.resolve(__dirname),
path.resolve(__dirname, '../src'),
],
},
{
test: /\.jsx?$/,
loader: 'happypack/loader?id=jsx-without-lodash-plugin',
include: [
path.resolve(__dirname, '../src/app/modules/insights/'),
],
exclude: /node_modules/,
},
{
test: /\.jsx?$/,
loader: 'happypack/loader?id=jsx-with-proptypes',
},
{
test: /\.jsx?$/,
loader: 'babel-loader',
query: {
presets: [['env', { include: ['babel-plugin-transform-es2015-template-literals'] }]],
},
},
{
test: /\.css$/,
use: getCssLoaders({
pwd: PWD,
debug: DEBUG,
}),
},
...getScssRules(DEBUG, PWD),
{
test: /\.less$/,
use: [DEBUG ? 'css-loader' : 'css-loader?minimize', 'less-loader'],
},
{
test: /\.txt$/,
loader: 'raw-loader',
},
{
test: /\.svg$/,
loader: 'spr-svg-loader',
},
{
test: /\.(png|jpg|jpeg|gif)$/,
loader: 'url-loader',
query: {
name: DEBUG ? '[path][name].[ext]' : '[hash].[ext]', // ?[hash]
limit: 10000,
},
},
{
test: /\.(woff|woff2)$/,
loader: 'url-loader?name=fonts/[name].[ext]&limit=65000&mimetype=application/font-woff',
},
{
test: /\.(otf|ttf)$/,
loader: 'url-loader?name=fonts/[name].[ext]&limit=65000&mimetype=application/octet-stream',
},
{
test: /\.eot$/,
loader: 'url-loader?name=fonts/[name].[ext]&limit=65000&mimetype=application/vnd.ms-fontobject',
},
{
test: /\.(wav|mp3)$/,
loader: 'file-loader',
query: {
name: DEBUG ? '[path][name].[ext]' : '[hash].[ext]', // ?[hash]
},
},
{
test: /\.pug/,
loader: 'pug-loader',
},
{
test: /\.html$/,
include: /src\/app/,
loader: StringReplacePlugin.replace({
replacements: [
{
//Replaces ES6 strings from languagePack to simple string
pattern: /__\(\s*`([^`]*)`\s*\)/gi,
replacement: (match, p1) => {
let replacedStr = p1;
replacedStr = replacedStr.replace(new RegExp('\\$\\{([\\w\\.\\:\\-]+)\\}', 'g'), '\' + $1 + \'');
return `'${replacedStr}'`;
},
},
{
//Following methods - look out carefully for the *quotes* (single/double)
//doing what i18nPlugin would do for html files - with the *single* quotes
pattern: /__\(\s*'(.+?)'\s*\)/g,
replacement: (match, p1) => {
const replacedStr = p1;
return `'${replacedStr}'`;
},
},
{
//doing what i18nPlugin would do for html files - with the *double* quotes
pattern: /__\(\s*"(.+?)"\s*\)/g,
replacement: (match, p1) => {
const replacedStr = p1;
return `"${replacedStr}"`;
},
},
],
}),
},
],
},
resolve: {
modules: [
path.resolve(PWD),
path.resolve(PWD, '..'),
'node_modules',
'web_modules',
'src',
],
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.webpack.js', '.web.js'],
alias: ALIAS,
// symlinks: false, //https://webpack.js.org/configuration/resolve/#resolve-symlinks, https://github.com/webpack/webpack/issues/1643
},
plugins: [getProvidePlugin(), getLoaderOptionPlugin({ debug: DEBUG }), ...getHappypackPlugin({ debug: DEBUG })],
resolveLoader: {
modules: ['node_modules', path.resolve(PWD, '../../node_modules'), path.resolve(PWD, './config/loaders/')],
alias: {
text: 'raw-loader', // treat text plugin as raw-loader
jst: 'ejs-loader',
style: 'style-loader',
imports: 'imports-loader',
},
},
bail: !DEBUG,
watch: DEBUG,
cache: DEBUG,
stats: DEBUG ?
{
colors: true,
reasons: false,
hash: VERBOSE,
version: VERBOSE,
timings: true,
chunks: false,
chunkModules: VERBOSE,
cached: VERBOSE,
cachedAssets: VERBOSE,
performance: true,
} :
{ all: false, assets: true, warnings: true, errors: true, errorDetails: false },
};
Another Edit
Alias as defined on webpack config also didn't do the trick.
https://webpack.js.org/configuration/resolve/#resolve-alias
Using Alias
To map the imports to the right files you'll need to use the config.resolve.alias field in the webpack configuration.
Where in your scenario will look like:
const config = {
resolve: {
alias: {
'app': path.resolve(__dirname, 'src/app/'),
},
},
};
I am not 100% sure I am doing it right, but I also specify paths key in tsconfig, like this:
"baseUrl": "./src",
"paths": {
"#common/*": ["./common/*"],
"#moduleA/*": ["./moduleA/*"],
"#moduleB/*": ["./moduleB/*"],
}
and it seems to work all right. # prefix is just something i do to discern between my modules and npm dependencies
I have a React-based web application and I'm trying to build an electron app out of it. I have gotten quite far and the app seems to load but somewhere in between I get an error saying require is not defined.
These are the versions of the tools I'm using:
webpack 3.6
react 15.6.1
electron 1.7.6
Here's a screenshot of the line where the error occurs:
Note that require is defined in Console - I read somewhere that this could be a race condition, but even if that's the case, what do I do about it?
Here's my webpack.config.js (note that I'm using the electron-renderer target):
var path = require('path');
var webpack = require('webpack');
var StatsPlugin = require('stats-webpack-plugin');
var devServerPort = 3808;
var presets = ['es2015', 'react', 'stage-0'];
var options = {
entry: {
'application': [
'react-hot-loader/patch',
'app/application.jsx'
]
},
output: {path: __dirname, filename: 'js/bundle.js' },
resolve: {
modules: [
path.join(__dirname, 'node_modules/'),
path.join(__dirname, 'app/')
],
extensions: ['.js', '.jsx']
},
node: {
__dirname: false,
__filename: false
},
plugins: [
// must match electron.webpack.manifest_filename
new StatsPlugin('manifest.json', {
// We only need assetsByChunkName
chunkModules: false,
source: false,
chunks: false,
modules: false,
assets: true
}),
new webpack.ProvidePlugin({
"React": "react",
}),
new webpack.ProvidePlugin({
"ReactDOM": "react-dom",
}),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
'process.env.BASE_URL': JSON.stringify('localhost:3000'),
'global': {}, // bizarre lodash(?) webpack workaround
'global.GENTLY': false // superagent client fix
})
],
module: {
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loaders: "babel-loader", query: { presets: ['react', 'es2015', 'stage-0'] }},
{ test: /\.jsx$/, exclude: /node_modules/, loaders: "babel-loader", query: { presets: presets }},
{ test: /\.css$/, loader: "style-loader!css-loader" },
{ test: /\.png$/, loader: "url-loader?limit=100000" },
{ test: /\.jpg$/, loader: "file-loader" },
{ test: /\.(png|)$/, loader: 'url-loader?limit=100000' },
{
test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "file-loader"
},
{ test: /\.scss$/, loaders: ["style-loader", "css-loader?sourceMap", "sass-loader?sourceMap"] },
{
test: /\.json$/,
loaders: ['json-loader']
}
]
},
};
options.target = 'electron-renderer';
module.exports = options;
I even tried using webpack-target-electron-renderer but it caused more problems.
I've had a similar issue in the past, if it is in fact the same problem here's how to solve it.
The require you have shown is within the wrapping IIFE, which means that this is not window but the function, meaning that when you try to find require it's not in scope. In order to fix this you need use imports-loader.
In your case, under module and then loaders, add:
{
test: require.resolve("/*require/import path which requires the file where require("url") is*/"),
use: "imports-loader?this=>window"
}
Hope this solves your problem.
You need to use something like browserify or babelify.
See a more in-depth explanation here.