Trying to import between multiple JS files - javascript

I'm creating a Todo app and I am using webpack to bundle multiple js files. I'm having trouble importing my functions and classes between the different js files. I keep receiving the error "SyntaxError: cannot use import statement outside a module.". I have set the entry in the webpack.config.js file to the index.js file. I can import from all the other js files into the index.js file and it works. Where I am having trouble is importing between all the js files themselves. I am fairly new to webpack and any help would be greatly appreciated. Thanks!
This is the task.js file code that I am trying to import into the ui.js file.
import { v4 as uuidv4 } from 'uuid';
export class Task {
constructor(title, description, dueDate) {
return Object.assign(this, { id: uuidv4(), title, description, dueDate, completed: false })
}
}
Here is the code in the ui.js file
import { Task } from './task.js';
const taskOne = new Task('Hello', "goodbye")
console.log(taskOne);
Here is the webpack.config.js file
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
assetModuleFilename: '[name][ext]'
},
devtool: 'source-map',
devServer: {
static: {
directory: path.resolve(__dirname, 'dist')
},
port: 3000,
open: true,
hot: true,
compress: true,
historyApiFallback: true
},
module: {
rules: [
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(png|jpg|jpeg|svg|gif)$/i,
type: 'asset/resource'
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'Todo App',
filename: 'index.html',
template: './src/template.html'
})
]
}

Related

Using web-worker in the library, but the chunk file can not be found in react application

There are two separate repo:
Library repo
React Web application
library provide 2 functions
func1 without using web-worker
func2 using web-worker
// func2
export const func2 = () => {
//.....
const worker = new Worker(new URL('./web-worker/worker.ts', import.meta.url));
//.....
}
bundle files from webpack5
then import it in react web application
func1 works fine
but got this error when I calling the func2
below is webpack config for the library
const path = require('path');
const config = {
mode: 'production',
entry: './src/index.ts',
module: {
rules: [
{
test: /.ts$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
presets: ['#babel/preset-env', '#babel/preset-typescript'],
},
},
],
},
output: {
filename: "index.js",
path: path.resolve(__dirname, 'dist'),
publicPath: "/",
library: {
type: 'umd',
},
},
resolve: {
extensions: ['.ts', '.js'],
},
devtool: 'source-map',
};
module.exports = config

Wepback. Loading chunk failed after using `import()`

I'm working on React project and I had found out that one of budles files is too big and I need to split it. So, I tried to use import() sintax:
import React from 'react';
import thumbnails from './thumbnails.json';
export default class Portfolio extends React.Component {
constructor(props) {
super(props);
import('react-image-gallery').then(module => {
const ImageGallery = module.default;
this.galleries = thumbnails.map((thumbnail, i) => {
let items = [];
for (let i = 0; i < thumbnail.gallery.amount; i++) {
items.push({
original: `${thumbnail.gallery.href}/${i}.png`,
thumbnail: `${thumbnail.gallery.href}/${i}m.png`,
})
}
return (
<div className="gallery">
<ImageGallery key={i} items={items} thumbnailPosition="left" showPlayButton={false}
onImageLoad={this.onGalleryLoad.bind(this, thumbnail.gallery.amount)}/>
<button className="gallery__close" onClick={this.onCloseClick.bind(this)}>×</button>
</div>
)
});
});
}
Portfolio is the main component for one page. Later, when I open the page, there's an error Uncaught (in promise) ChunkLoadError: Loading chunk 0 failed.
As I saw, JavaScript tries to load file 0.bundle.js from the portfolio directory. While needed chunk is 0.chunk.js that is located in the root directory.
Here's my Wepback config:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = env => {
const isDev = env.MODE === 'development';
return {
mode: isDev ? 'development' : 'production',
devtool: 'source-map',
entry: {
'./home/script': './home/script.jsx',
'./portfolio/script': './portfolio/script.jsx',
'./prices/script': './prices/script.jsx',
'./contacts/script': './contacts/script.jsx',
'./extra/script': './extra/script.jsx',
'./extra/locations/script': './extra/locations/script.jsx',
'./extra/poses/script': './extra/poses/script.jsx',
'./extra/stylists/script': './extra/stylists/script.jsx',
'./extra/studios/script': './extra/studios/script.jsx',
},
output: {
path: __dirname,
publicPath: __dirname,
filename: '[name].bundle.js',
chunkFilename: '[name].chunk.js',
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['#babel/preset-env', '#babel/react'],
plugins: [
'#babel/plugin-proposal-class-properties',
'#babel/plugin-transform-runtime',
'#babel/plugin-syntax-dynamic-import',
]
}
}
},
],
},
optimization: {
minimize: !isDev,
minimizer: [new TerserPlugin({
test: /.js$/i,
extractComments: false,
terserOptions: {
output: {
comments: false,
},
},
})],
},
resolve: {
extensions: ['.jsx', '.js'],
}
}
};
Try changing your output object to
output: {
......
chunkFilename: '[name].[chunkhash].js',
}
Check this out for reference https://github.com/webpack/webpack/issues/9207#issuecomment-499448929
I've found the answer. To escape searching in subrirectories, you should use publicPath: '/' in the output option of webpack. It was sugested to use chunk hashes, but as I tried it, it's not really nesessary. The whole solution is here:
output: {
path: __dirname,
publicPath: '/',
filename: '[name].bundle.js',
chunkFilename: './assets/chunks/[name].chunk.js',
}
The ./assets/chunks/ part is not required. It's just for holding all chunks in one directory

Imports and requires are not loading properly in Webpack

I am using Vue with Webpack, but I when I import or require another file to be included into my main document, the file seems to have loaded, as in it doesn't give me any errors, but the imports within the files do not load, and I can't use any variables from the files. For example, I have this main document:
import './bootstrap';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
let Default = Vue.component('Default', {
template: `
<li>
This is home
</li>
`
});
let About = Vue.component('About', {
template: `
<li>
This is about us maaan
</li>
`
});
var router = new VueRouter({
routes: [
{ path: '/', component: Default },
{ path: '/about', component: About }
]
})
require('./sass/styles.scss');
new Vue({
el: '#app',
router: router
})
...and my bootstrap file is simply:
import Vue from 'vue';
import axios from 'axios';
I get the following error: Uncaught ReferenceError: Vue is not defined, as if the file had not been included. If I make any changes to the path, I get a file not found error, so I imagine that the file is located. the same for any variables in the file, they are not available in the main file afterwards. This is my webpack.config.js:
var path = require('path')
var webpack = require('webpack')
var inProduction = (process.env.NODE_ENV === 'production');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: 'dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
// the "scss" and "sass" values for the lang attribute to the right configs here.
// other preprocessors should work out of the box, no loader config like this necessary.
'scss': 'vue-style-loader!css-loader!sass-loader',
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: 'images/[name].[ext]?[hash]'
}
},
{
test: /\.s[ac]ss$/,
use: ExtractTextPlugin.extract({
use: ['css-loader', 'sass-loader'],
fallback: 'style-loader'
})
}
]
},
plugins: [
new ExtractTextPlugin({
filename: 'styles.css',
disable: process.env.NODE_ENV === "development"
})
],
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
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: false
// }
// }),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
Many thanks!

Module not found: Error: Cannot resolve module 'components/app'. webpack + reactjs issue

I'm newbie in webpack and react. hope you can help me.
I faced a problem and can't find any working solution in the internet.
When i trying to run webpack-dev-serverI geting "Module not found: Error: Cannot resolve module 'components/app'" error all the time.
Here my files structure.
root/ webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = {
devtool: 'inline-source-map',
entry: [
'webpack-dev-server/client?http://127.0.0.1:8080/',
'webpack/hot/only-dev-server',
'./src'
],
output: {
path: path.join(__dirname, 'public'),
filename: 'bundle.js'
},
resolve: {
moduleDirectories: ['node_modules', 'src'],
extensions: ['', '.js']
},
module: {
loaders: [{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
};
root/ .babelrc
{
presets: ["react", "es2015"],
plugins: ["react-hot-loader/babel"]
}
root/src/index.js
import React from 'react';
import { render } from 'react-dom';
import App from 'components/app';
render(<App />, document.getElementById('app'));
root/src/components/app.js
import React from 'react';
export default class App extends React.component {
render() {
return (
<div>
<h1>Hello There</h1>
</div>
);
}
}
I agree with Robert Moskal answer, use Relative path to import, at the same time if you really want the absolute path to work you may have to add one more line in your webpack.config.js inside your resolve section of it add this below line
root: path.resolve('./src'),
this will help to resolve the root and you can easily import using absolute path from folders inside the src folder. I would show you my sample webpack.config.js below
'use strict';
const path = require('path');
const loaders = require('./webpack/loaders');
const plugins = require('./webpack/plugins');
const applicationEntries = process.env.NODE_ENV === 'development'
? ['webpack-hot-middleware/client?reload=true']
: [];
const mainEntry = process.env.NODE_ENV === 'development'
? './src/sample/index.tsx'
: './src/lib/index.tsx';
module.exports = {
entry: [mainEntry].concat(applicationEntries),
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js',
publicPath: '/',
sourceMapFilename: '[name].js.map',
chunkFilename: '[id].chunk.js',
},
devtool: process.env.NODE_ENV === 'production' ?
'source-map' :
'inline-source-map',
resolve: {
root: path.resolve('./src'),
extensions: [
'',
'.webpack.js',
'.web.js',
'.tsx',
'.ts',
'.js',
'.json',
],
},
plugins: plugins,
devServer: {
historyApiFallback: { index: '/' },
},
module: {
preLoaders: [
loaders.tslint,
],
loaders: [
loaders.tsx,
loaders.html,
loaders.css,
loaders.scss,
loaders.eot,
loaders.svg,
loaders.ttf,
loaders.woff,
loaders.json,
{
test: /\.png$/,
loader: 'url-loader',
query: { mimetype: 'image/png' },
},
],
},
externals: {
'react/lib/ReactContext': 'window',
'react/lib/ExecutionEnvironment': true,
'react/addons': true,
},
};
You need to specify a relative path to app in your index.js file. So
import App from './components/app'
Without the relative path notation, the module import system looks in the node_modules directory.
You're looking for module aliasing. The resolve section of your config should look something like:
const path = require('path');
resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
extensions: ['', '.js'],
alias: {
components: path.resolve(__dirname, 'src/components/')
}
}
This is equivalent to the paths option in TypeScript config files.

Sass loader not loading style

Webpack is slick... If only I could get it to work. I have two files.
App.js
App.scss
I want to import the styles from App.scss and use them in App.js
Here is my code.
// App.js
import React, {Component} from 'react';
import s from './App.scss';
class App extends Component {
render() {
return (
<div className={s.app}>
</div>
);
}
}
console.log('what is in s ' + JSON.stringify(s));
export default App;
And Sass file.
// App.scss
.app {
width: 100%;
height: 100%;
background-color: blue;
}
Console shows that s is an empty object. I would expect to see {app: ...}.
Weback is setup like this.
// webpack.config.js
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'source-map',
entry: [
'./src/client',
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/dev-server'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
module: {
loaders: [
{
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
},
{
test: /\.js$/,
loader: 'babel-loader',
include: path.join(__dirname, 'src')
}]
},
devServer: {
contentBase: './dist',
hot: true
}
};
No errors from webpack. No errors in the console.
After much searching I found this Github issue. Solution is to change this line in webpack.config.js
loaders: ['style', 'css', 'sass']
to
loader: 'style!css?modules!sass'

Categories

Resources