Copy files from node_modules to dist dir - javascript

I am trying to copy library from node_modules to dist folder using html-webpack-plugin, the library name is wsrpc-python
That's my webpack config, I set file-loader but it doesn't help.
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const { VueLoaderPlugin } = require('vue-loader')
const vueLoaderConfig = require('./vue-loader.conf')
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js',
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath:
process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
externals: {
"wsrpc-python": "WSRPC",
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'#': resolve('src')
}
},
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
include: [
resolve('src'),
resolve('test'),
resolve('node_modules/webpack-dev-server/client')
]
},
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include: [resolve('src/icons')],
options: {
symbolId: 'icon-[name]'
}
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
exclude: [resolve('src/icons')],
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
},
{
test: /wsrpc-python\/js\//,
loader: 'file-loader'
},
]
},
plugins: [new VueLoaderPlugin()],
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}

Adding onto #tony19's answer, you need to set a to and from path in copy-webpack-plugin.
It should look like this:
new CopyWebpackPlugin([
{ from: 'node_modules/wsrpc-python/*.js', to: '/dist' },
]),

By default CopyWebpackPlugin will look for the file in the current dir, to provide the right dir we need to use require.resolve('your-package-name/dir/file-name')
plugins: [
new CopyWebpackPlugin({
patterns: [{
from: require.resolve('my-package-name/dist/index.css'),
to: '[name].min.css'
}]
})
]

Use the CopyWebpackPlugin instead:
webpack.config.js:
const CopyPlugin = require('copy-webpack-plugin')
module.exports = {
plugins: [
...
new CopyPlugin([
'node_modules/wsrpc-python/*.js',
]),
],
}
GitHub demo

CopyWebpackPlugin didn't work for me either.
I just use a custom inline plugin, like so: https://gist.github.com/Venryx/c473c60ea0f10a2620f2d9d00c06e6c7

Related

Blank page with webpack after conversion to typescript

I have a project that I was using with plain JS, built with rekit. I got tired of using JSDoc to specify the types, and I wanted to use typescript instead. I converted the entire codebase to TS using ts-migrate, but I am having serious problems with webpack.
The project seems to compile just fine, no errors on webpack side, and If I turn on performance hints it tells me that the size of some assets is too big, just like before.
However, when I open the page on the browser, it still downloads the bundle, but it is not executed. I can't understand what is wrong, if it is the TS configuration, webpack configuration or just the dev server. Below there are the two relevant files, a common file for shared configs between dev and prod, and the dev file. The webpack dev server and everything was working before, it is just after the migration to TS that fails.
If you prefer to see the changes in context, here is the pull request where I am doing the migration
Here is the common file:
const extensions = ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx', 'ts', 'tsx'];
const rules = [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react', '#babel/preset-typescript'],
},
},
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
];
module.exports = {
extensions,
rules,
};
And here is the webpack dev config:
const autoprefixer = require('autoprefixer');
const path = require('path');
const webpack = require('webpack');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getClientEnvironment = require('./env');
const paths = require('./paths');
const { extensions, rules } = require('./webpack.common');
const publicPath = '/';
const publicUrl = '';
const env = getClientEnvironment(publicUrl);
module.exports = {
mode: 'development',
devtool: 'cheap-module-source-map',
entry: [
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appIndexJs,
paths.appIndexStyle,
],
output: {
pathinfo: true,
filename: 'static/js/bundle.js',
chunkFilename: 'static/js/[name].chunk.js',
publicPath: publicPath,
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
},
resolve: {
modules: ['node_modules', paths.appNodeModules].concat(
process.env.NODE_PATH.split(path.delimiter).filter(Boolean),
),
extensions,
plugins: [
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
new TsconfigPathsPlugin({ logLevel: 'info', extensions }),
],
},
module: {
strictExportPresence: true,
rules: [
...rules,
{
oneOf: [
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
},
},
{
test: /\.less$/,
loader: 'style-loader!css-loader?sourceMap!less-loader?sourceMap',
},
{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
},
},
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: ['>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9'],
flexbox: 'no-2009',
}),
],
},
},
],
},
{
loader: require.resolve('file-loader'),
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
],
},
],
},
plugins: [
new webpack.EnvironmentPlugin(env.raw),
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
env: env.raw,
}),
new webpack.HotModuleReplacementPlugin(),
new CaseSensitivePathsPlugin(),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
node: {
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
},
performance: {
hints: false,
},
};
As you can see on this screenshot, there is no error on the console and the bundle is correctly being downloaded:
If I run a production build, all it "bundles" are the style loader and the webpack runtime. Here is the result of the webpack bundle analyzer:

How do I access process.env.VAR in Webpack 5?

I've never used Webpack before and I'm working on a project that's just vanilla JS and HTML. I'm having an issue accessing the values I set in .env. Here's my config.
const path = require("path");
const dotenv = require('dotenv');
var webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Dotenv = require('dotenv-webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = () => {
env = dotenv.config().parsed;
const envKeys = Object.keys(env).reduce((prev, next) => {
prev[`process.env.${next}`] = JSON.stringify(env[next]);
return prev;
}, {});
return {
entry: {
main: './src/index.js'
},
output: {
path: path.join(__dirname, '../build'),
filename: '[name].bundle.js'
},
mode: 'development',
devServer: {
contentBase: "./src/",
publicPath: "./src/",
compress: true,
port: 9000,
overlay: true,
disableHostCheck: true
},
devtool: 'inline-source-map',
resolve: {
alias: {
process: "process/browser"
}},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|svg|jpe?g|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'assets/'
}
}
]
},
{
test: /\.html$/,
use: {
loader: 'html-loader',
options: {
//attributes: ['img:src', ':data-src'],
minimize: true
}
}
}
]
},
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new Dotenv(),
new webpack.DefinePlugin(envKeys),
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
}),
]
}
};
As you can see, I'm using dotEnv, definePlugin, and even the dotEnv-webpack plugin. Unfortunately, none of these solutions seem to allow me to access process.env.originURL.
originURL=https://localhost:3000
I'm not importing or requiring anything in my javascript file, index.js. I'm assuming this should work, but the console tells me that process is undefined.
console.log(process.env.originURL);
How can I access process.env.originURL in my index.js?
It should work. Maybe you could try this version:
new Dotenv({ systemvars: true })
If it still doesn't work, please show your package.json, as well as you .env file (randomize the values of course). Is .env at the root of you app?

Webpack can't resolve type from io-ts

I'm currently using TS + React to make a simple application with some API requests to a server. When I try to use io-ts to decode the response, webpack responds with Module not found: Error: Can't resolve '../shared/Response' - if I remove the usage of io-ts to decode the response, I don't get that error.
My folder structure is
src
client
PlayerTimer.tsx
<skipped>
server
<skipped>
shared
Phase.d.ts
Response.d.ts
Phase.d.ts contains the following:
import * as t from 'io-ts';
export const PhaseDecode = t.union([
t.literal(1),
t.literal(2),
t.literal(3),
t.literal(4),
t.literal(5),
]);
export type Phase = t.TypeOf<typeof PhaseDecode>
Response.d.ts contains the following:
import * as t from 'io-ts';
import { DateFromISOString as IoDate } from 'io-ts-types/DateFromISOString';
import { PhaseDecode } from './Phase';
const ApiResponseDecode = t.type({
turnNumber: t.number,
phase: PhaseDecode,
breakingNews: t.union([t.string, t.null]),
active: t.boolean,
phaseEnd: IoDate
});
type ApiResponse = t.TypeOf<typeof ApiResponseDecode>
export { ApiResponseDecode, ApiResponse as default };
PlayerTimer.tsx contains a bunch of React components, but this is reproducible with just the following code at the top
import { ApiResponseDecode } from '../shared/Response';
const temp = {};
if (ApiResponseDecode.is(temp)) {
console.log('Webpack fails');
}
My webpack config is:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const outputDirectory = 'dist';
module.exports = {
entry: ['babel-polyfill', './src/client/index.tsx'],
output: {
path: path.join(__dirname, outputDirectory),
filename: './js/[name].bundle.js'
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
},
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader'
},
{
test: /\.less$/,
use: [
{ loader: 'style-loader' },
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: './Less',
hmr: process.env.NODE_ENV === 'development',
},
},
{ loader: 'css-loader' },
{
loader: 'less-loader',
options: {
strictMath: true,
noIeCompat: true,
}
},
]
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
],
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000'
},
]
},
resolve: {
extensions: ['*', '.ts', '.tsx', '.js', '.jsx', '.json', '.less']
},
devServer: {
port: 3000,
open: true,
hot: true,
historyApiFallback: true,
proxy: {
'/api/**': {
target: 'http://localhost:8050',
secure: false,
changeOrigin: true
}
}
},
plugins: [
new CleanWebpackPlugin([outputDirectory]),
new HtmlWebpackPlugin({
template: './public/index.html',
favicon: './public/favicon.ico',
title: 'Test application',
}),
new MiniCssExtractPlugin({
filename: './css/[name].css',
chunkFilename: './css/[id].css',
}),
new CopyPlugin([
{ from: './src/client/Assets', to: 'assets' },
])
],
};
I fixed this by moving the type definitions and the io-ts definitions into separate files. I don't really understand why that works but I'll add this incase someone else finds this

Webpack - Sass loader not compiling Sass

I'm trying to introduce Sass-loader to an existing project so as to be able to use Sass in my React components. I've set this up successfully before in my own boiler plates and had no issues but for some reason with the current configuration it doesn't seem to play. It doesn't give any errors but rather doesn't do anything with my .scss file i'm trying to import.
I can see that there is some loaders in the cssLoaders config for Webpack which could be the culprit but I am only targeting .scss/ .sass files with the rule
test: /\.s(a|c)ss$/
so I wouldn't have thought this would affect it at all.
I have webpack setup with a common file and one for development. Here are both those files:
webpack.common.js
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const ErrorOverlayPlugin = require('error-overlay-webpack-plugin');
const webpack = require('webpack');
const path = require('path');
require('babel-polyfill');
const Dotenv = require('dotenv-webpack');
module.exports = {
entry: {
main: ['babel-polyfill', './src/index.js']
},
output: {
filename: '[name].[hash].js',
path: path.resolve('./dist')
},
module: {
rules: [
{
test: /\.js$/,
exclude: ['node_modules'],
use: [{ loader: 'babel-loader' }]
},
{
test: /\.s(a|c)ss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.(png|jpg|gif|svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
outputPath: 'images/'
}
}
]
},
{
test: /\.(woff(2)?|ttf|eot|otf)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
}
]
},
plugins: [
new ErrorOverlayPlugin(),
new webpack.HotModuleReplacementPlugin(),
new HtmlWebPackPlugin({
template: 'index.html'
}),
new Dotenv(),
new CleanWebpackPlugin(['dist'])
]
};
And here is webpack.dev.js
const path = require('path');
const webpack = require('webpack');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const paths = require('../paths');
module.exports = require('./webpack.config.base')({
bail: false,
devtool: 'cheap-module-eval-source-map',
stats: 'errors-only',
performance: {
hints: false
},
entry: {
main: [
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appPolyfillsJs,
require.resolve('react-error-overlay'),
paths.appIndexJs
]
},
output: {
pathinfo: true,
filename: 'static/js/[name].js',
chunkFilename: 'static/js/[name].chunk.js',
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath)
},
// Load the CSS in a style tag in development
cssLoaders: [
{
loader: require.resolve('style-loader'),
options: {
sourceMap: true
}
},
{
loader: require.resolve('css-loader'),
options: {
modules: false,
sourceMap: true,
importLoaders: 1
}
},
{
loader: require.resolve('postcss-loader'),
options: { sourceMap: true }
}
],
babelQuery: {
cacheDirectory: true
},
plugins: [].concat([
new ProgressBarPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new CircularDependencyPlugin({
exclude: /a\.js|node_modules/,
failOnError: true
})
])
});
The part that I have added to the configuration is in webpack.common:
{
test: /\.s(a|c)ss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
I then just import it in the module like so:
import React, { PureComponent } from 'react';
import './test.scss';
...
Can anyone spot why the configuration is wrong?
The sass-loader requires node-sass and webpack as peerDependency.
Make sure node-sass is installed and edit the loader webpack.dev.js like so:
{
loader: "sass-loader",
options: {
includePaths: ["absolute/path/a", "absolute/path/b"]
}
}

multiple errors auth0 react apollo babel webpack

I'm having a little bit of an issue when I want to implement auth0 on my project.
Whenever I solve one problem I run into another, it's always the same 3 errors :
-require is not a function
-window is not defined
-missing class properties
I've tried solving it by playing with the babelrc, changing the order of the presets
And in webpack I've added the famous as below:
"plugins: [new webpack.DefinePlugin({ 'global.GENTLY': false })],"
in webpack to no avail
I'm providing the package json/ babelrc & web pack without the modifications I cited above so you can see the "base" without the failed attempts at fixing it
Also providing the screenshots with the errors
Thanks in advance
https://imgur.com/a/8TT3v44
for the errors
this is in babelrc
{
"presets": [
"#babel/preset-react",
["#babel/preset-env", { "modules": false }],
["#babel/preset-stage-0", { "decoratorsLegacy": true }]
],
"env": {
"development": {
"compact": false
},
"jest": {
"presets": ["#babel/preset-env", "#babel/preset-react"]
}
},
"plugins": [
"#babel/plugin-proposal-export-default-from",
[
"react-intl",
{
"messagesDir": "./extracted_messages/",
"enforceDescriptions": true
}
]
]
}
and this is the webpack
const path = require('path')
const CopyPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const webpack = require('webpack')
const distDir = path.join(__dirname, '../dist')
const srcDir = path.join(__dirname, '../src')
module.exports = [
{
name: 'client',
target: 'web',
mode: 'development',
entry: `${srcDir}/client.jsx`,
output: {
path: distDir,
filename: 'client.js',
publicPath: '/dist/'
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
config: path.join(__dirname, '../config'),
utils: path.join(__dirname, '../src/utils'),
toolbox: path.join(__dirname, '../src/components/toolbox')
}
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules\/)/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.(jpe?g|png|gif)$/,
loader: 'file-loader',
query: { name: 'assets/images/[name].[ext]' }
},
{
test: /\.(woff2?|eot|ttf|otf)$/,
loader: 'file-loader',
query: { name: 'assets/fonts/[name].[ext]' }
}
]
},
plugins: [
new webpack.DefinePlugin({ 'global.GENTLY': false }),
new MiniCssExtractPlugin({
filename: 'styles.css'
}),
new CopyPlugin([{ from: `${srcDir}/favicon.ico`, to: distDir }])]
},
{
name: 'server',
target: 'node',
mode: 'development',
entry: `${srcDir}/server.jsx`,
output: {
path: distDir,
filename: 'server.js',
libraryTarget: 'commonjs2',
publicPath: '/dist/'
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
config: path.join(__dirname, '../config'),
utils: path.join(__dirname, '../src/utils'),
toolbox: path.join(__dirname, '../src/components/toolbox'),
inherits: 'inherits/inherits_browser.js',
superagent: 'superagent/lib/client',
emitter: 'component-emitter',
}
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules\/)/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
{
loader: 'isomorphic-style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.(jpe?g|png|gif)$/,
loader: 'file-loader',
query: { name: 'assets/images/[name].[ext]' }
},
{
test: /\.(woff2?|eot|ttf|otf)$/,
loader: 'file-loader',
query: { name: 'assets/fonts/[name].[ext]' }
}
]
},
plugins: [
new webpack.DefinePlugin({ 'global.GENTLY': false }),
new CopyPlugin([{ from: `${srcDir}/favicon.ico`, to: distDir }])]
}
]
I ran into this problem while writing for our blog. Our suggested fix is this;
function whatYouRunOnPageLoad() {
if (typeof window !== undefined) {
auth0.parseHash(... etc ...)
}
}
parseHash requires window, which does not exist as part of your render steps. Auth0.js cannot run from serverside, which is what is "accidentally" happening when you try to render it the way you are.
Window error solved by doing:
if(global.window){...}
and later on by just not calling the function I was using at inappropriate times.
Require is not a function solved with:
[new webpack.DefinePlugin({ 'global.GENTLY': false })]
in the webpack config at plugins (dev AND prod, idk why) + importing it with require and not import.
Webpack module error solved by changing the order of the presets in bablerc.

Categories