webpack: 'import' not working whereas 'require' works okay - javascript

I have a strange issue using webpack.
This my webpack.config.js:
import webpack from "webpack";
import path from "path";
//not working: import ExtractTextPlugin from "extract-text-webpack-plugin";
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const GLOBALS = {
"process.env.NODE_ENV": JSON.stringify("production"),
__DEV__: false
};
export default {
debug: true,
devtool: "source-map",
noInfo: true,
entry: "./src/bootstrap",
target: "web",
output: {
path: path.join(__dirname, "dist"),
publicPath: "/",
filename: "bundle.js"
},
resolve: {
root: path.resolve(__dirname),
alias: {
"~": "src"
},
extensions: ["", ".js", ".jsx"]
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.DefinePlugin(GLOBALS),
new ExtractTextPlugin("styles.css"),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin()
],
module: {
loaders: [
{ test: /\.jsx?$/, include: path.join(__dirname, "src"), loaders: ["babel"] },
{ test: /\.eot(\?v=\d+.\d+.\d+)?$/, loader: "file" },
{ test: /\.(woff|woff2)$/, loader: "file-loader?prefix=font/&limit=5000" },
{ test: /\.ttf(\?v=\d+.\d+.\d+)?$/, loader: "file-loader?limit=10000&mimetype=application/octet-stream" },
{ test: /\.svg(\?v=\d+.\d+.\d+)?$/, loader: "file-loader?limit=10000&mimetype=image/svg+xml" },
{ test: /\.(jpe?g|png|gif)$/i, loaders: ["file"] },
{ test: /\.ico$/, loader: "file-loader?name=[name].[ext]" },
{
test: /(\.css|\.scss)$/,
loader: ExtractTextPlugin.extract("css?sourceMap!sass?sourceMap")
}
]
}
};
As you can see: I set up an alias "~" pointing to my "src" directory.
According to webpack documentation I should be able to import modules this way:
import { ServiceStub } from "~/utilities/service-stub";
HINT: File service-stub.js sits here: [__dirname]/src/utilities/service-stub.js.
However, this does not work since webpack is throwing an error ("Path not found.").
When I userequire instead of import, everything works fine:
const { ServiceStub } = require("~/utilities/service-stub");
The same issue is in webpack.config.js itself:
import webpack from "webpack";
import path from "path";
//not working: import ExtractTextPlugin from "extract-text-webpack-plugin";
const ExtractTextPlugin = require("extract-text-webpack-plugin");
Here some modules import well with import (modules webpack and path), some do not (module extract-text-webpack-plugin).
I worked through dozens of forums, but found no solution yet.

The problem is ESLint - not webpack.
When you are using aliases in webpack like this
resolve: {
root: path.resolve(__dirname),
alias: {
"~": "src"
},
extensions: ["", ".js", ".jsx"]
}
and you are importing this way
import { ServiceStub } from "~/services/service-stub";
ESLint cannot resolve the alias and reports an error.
To get it work you must tell ESLint to ignore some rule with "import/no-unresolved": 0. This seems to be okay because if an imported file is actually missing, webpack reports an error itself.

Related

Disable Strict Mode in None Module Library

I want to bundle a JavaScript project by WebPack but there is more problems in none-module libraries because imported them by 'import' capability,ECMAScript 6 module loader run strict mode by default and it tack more errors.
Question :
How can I import none module libraries without strict mode to bundle them by WebPack?
index.js
import '../examples/js/libs/draco/draco_encoder.js';
import './js/libs/codemirror/codemirror.js';
import './js/libs/codemirror/mode/javascript.js';
import './js/libs/codemirror/mode/glsl.js';
...
webpack.config.js
const path = require('path');
const webpack = require('webpack');
// webpack.config.js
module.exports = {
entry: {
polyfills: './editor/polyfills',
index: './lib/index.js',
},
mode: 'development',
output: {
path: __dirname,
publicPath: '/',
filename: './editor/[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
devServer: {
watchContentBase: true,
publicPath: "/",
contentBase: "./",
hot: true,
port: 8080,
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['#babel/preset-env']
}
}
}
]
}
};
babel.config.json
{
"presets": [
"#babel/preset-env"
]
}
I tryed :
babel
esmify
browserify
Shimming in WebPack
...
Thanks for your attention.
Webpack enables use of loaders to preprocess files. This allows you to bundle any static resource way beyond JavaScript.
About loaders: Loaders.
You can easily write your own loaders using Node.js : Writing Loader.
For execute JS script once in global context that can solved my problem : Script Loader

Webpack can't resolve relative path import express static

I'm working on an outlook addin I have an express server running. I am setting webpack because I need to transpile js to es5 to make it work in Outlook Desktop. Here is the simplified project structure.
/public
/javascripts
ssoAuth.js
/addin
/commmands
commands.js
commands.html
/server
/bin
/helpers
app.js
The public folder is set as a static folder in my express server
app.use(express.static(path.join(__dirname, '../public'),
My problem is in commands.js I import ssoAuth.js with es6 module import with relative path :
import getGraphAccessToken from "/javascripts/ssoAuthES6.js";
It works fine when I run node ./server/app.js and load my outlook addin, but when I want to use Webpack to bundle, the import is not working, I get :
ERROR in ./addin/commands/commands.js
Module not found: Error: Can't resolve '/javascripts/ssoAuth.js'
I can't figure out how to configure webpack to allow the imports from the public folder.
Here are my webpack config files :
webpack.config.js :
const config = {
devtool: "source-map",
entry: {
polyfill: "#babel/polyfill",
commands: "./addin/commands/commands.js"
},
resolve: {
extensions: [".ts", ".tsx", ".html", ".js"]
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env"]
}
}
},
{
test: /\.html$/,
exclude: /node_modules/,
use: "html-loader"
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: "file-loader"
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
filename: "commands.html",
template: "./addin/commands/commands.html",
chunks: ["polyfill", "commands"]
})
]};
webpack.server.config.js :
return ({
entry: {
server: './server/bin/www',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
__dirname: false,
__filename: false,
},
externals: [nodeExternals()],
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
plugins: [
new CopyWebpackPlugin([
{
to: "./public",
from: "./public"
}
])
]})
Can you help figure this out ? Is there a better folder structure that I should use to make it work ?
Thanks
You're using an absolute path
import getGraphAccessToken from "/javascripts/ssoAuthES6.js";
// ^ this will look in your topmost directory on your OS
The relative path, from commands.js, would be:
import getGraphAccessToken from "../../javascripts/ssoAuthES6.js";
Alternatively, you can set Webpack to look for modules from your root directory by adding the following to your webpack configuration:
{
// ...
resolve: {
modules: [path.resolve(__dirname, "src"), "node_modules"],
},
// ...
}
Then you can import from your project's root directory from anywhere, like so:
import getGraphAccessToken from "javascripts/ssoAuthES6.js";
Some other points:
Since you're setting the extensions: [".ts", ".tsx", ".html", ".js"], you don't need to provide file extensions for those imports
You specify .ts and .tsx in your webpack config, but you are using .js files. Consider removing the Typescript extensions
If you are using Typescript, you will need to update import paths in your tsconfig.json
You can consider import path aliases in both Webpack and Typescript to be more explicit that your imports are coming from your project root. Instructions here

Unexpected token You may need an appropriate loader to handle this file type.importing strapi sdk

Hi I am trying to import javascript strapi sdk (link) in my new project which is configured using web pack
Here is my code yet
index.ts file
import * as $ from 'jquery';
import Strapi from 'strapi-sdk-javascript'
const strapi = new Strapi('http://localhost:1337')
here is my webpack.config.file
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: './src/index.ts',
module: {
rules: [
{
test: /\.js$/,
use:
{loader: 'babel-loader',
options: {
presets: ['env']
}
},
// include: [path.resolve(__dirname, "./src/app")],
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
alias: {
$: "jquery/src/jquery",
}
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist'
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
template: 'src/assets/template.html'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
and this is giving my this error
what am i doing wrong here . please
help thanks in advance
You can try something like this
// Process JS with Babel.
{
test: /\.(js|jsx|mjs)$/,
include: [path.resolve(__dirname,"./src/app")path.resolve('node_modules/strapi-sdk-javascript')],
loader: require.resolve('babel-loader'),
},

Navigator undefined on React Typescript Firebase project

I've been googling for a couple hours now and can't seem to resolve my issue.
I have a webpack/React/Typescript/Mobx setup and am attempting to use firebase.
Here is my webpack config: (boilerplate from this repo)
var webpack = require('webpack');
var path = require('path');
// variables
var isProduction = process.argv.indexOf('-p') >= 0;
var sourcePath = path.join(__dirname, './src');
var outPath = path.join(__dirname, './dist');
// plugins
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var WebpackCleanupPlugin = require('webpack-cleanup-plugin');
module.exports = {
context: sourcePath,
entry: {
main: './main.tsx'
},
output: {
path: outPath,
filename: 'bundle.js',
chunkFilename: '[chunkhash].js',
publicPath: '/'
},
target: 'web',
resolve: {
extensions: ['.js', '.ts', '.tsx'],
// Fix webpack's default behavior to not load packages with jsnext:main module
// (jsnext:main directs not usually distributable es6 format, but es6 sources)
mainFields: ['module', 'browser', 'main'],
alias: {
app: path.resolve(__dirname, 'src/app/'),
assets: path.resolve(__dirname, 'src/assets/')
}
},
module: {
rules: [
// .ts, .tsx
{
test: /\.tsx?$/,
use: [
isProduction
? 'ts-loader'
: {
loader: 'babel-loader',
options: {
babelrc: false,
plugins: ['react-hot-loader/babel']
}
},
'ts-loader'
],
// : ['babel-loader?plugins=react-hot-loader/babel&presets=', 'ts-loader'],
exclude: /node_modules/
},
// css
{
test: /\.css$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
query: {
modules: true,
sourceMap: !isProduction,
importLoaders: 1,
localIdentName: '[local]__[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('postcss-import')({ addDependencyTo: webpack }),
require('postcss-url')(),
require('postcss-cssnext')(),
require('postcss-reporter')(),
require('postcss-browser-reporter')({
disabled: isProduction
})
]
}
}
]
})
},
{
test: /\.css$/,
include: /node_modules/,
use: ['style-loader', 'css-loader']
},
// static assets
{ test: /\.html$/, use: 'html-loader' },
{ test: /\.(png|jpg)$/, use: 'url-loader?limit=10000' },
{ test: /\.webm$/, use: 'file-loader' }
]
},
optimization: {
splitChunks: {
name: true,
cacheGroups: {
commons: {
chunks: 'initial',
minChunks: 2
},
vendors: {
test: /[\\/]node_modules[\\/]/,
chunks: 'all',
priority: -10
}
}
},
runtimeChunk: true
},
plugins: [
new WebpackCleanupPlugin(),
new ExtractTextPlugin({
filename: 'styles.css',
disable: !isProduction
}),
new HtmlWebpackPlugin({
template: 'assets/index.html'
})
],
devServer: {
contentBase: sourcePath,
hot: true,
inline: true,
historyApiFallback: {
disableDotRule: true
},
stats: 'minimal'
},
devtool: 'cheap-module-eval-source-map',
node: {
// workaround for webpack-dev-server issue
// https://github.com/webpack/webpack-dev-server/issues/60#issuecomment-103411179
fs: 'empty',
net: 'empty'
}
};
Just by including firebase in my app i relentlessly end up with this error:
Uncaught TypeError: Cannot read property 'navigator' of undefined auth.esm.js?69b5:10
I have tested by including a simple component like so:
import * as React from 'react';
import * as Styles from './styles.css';
import 'app/utils/FirebaseUtil';
interface TestProps {}
export const Test: React.StatelessComponent<TestProps > = () => (
<div className={Styles.root}>
{'Hello World'}
</div>
);
FirebaseUtil:
import * as firebase from 'firebase';
const config = {
apiKey: '**my key here**',
authDomain: '** my domain here **'
};
firebase.initializeApp(config);
export const fbAuth = firebase.auth;
No matter what I seem to do I get the navigator error. Even if i dont export the auth object. As far as I can tell its related to babel-loader adding strict-mode according to this SO question, i think? All other related searches seem to have to do with firebase-ui, which i am not using in any way.
But I have no idea how he manages to turn off strict mode, not to mention the OP is not using typescript and I am using ts-loader in this case. I can't for the life of me figure out how to get it working. Aside from all of this if I do try use the firebase object for auth() for example I get a bunch of warnings from webpack about auth not existing on the firebase object. Totally stumped.
So in case anyone else runs into this problem. It appears it was a package version issue. Im assuming that the package versions specifically included in the boilerplate i used didn't play well with firebase.
I updated typescript, react-hot-loader, and most likely the issue webpack from version 3.0.4 to 4.12.1 and things seem to be working ok now. Also with the updates I now import firebase like so:
import firebase from '#firebase/app';
import '#firebase/auth';
Hope this helps someone.
In my case I fixed this importing functions
import firebase from 'firebase/app'
import 'firebase/functions'
import 'firebase/analytics'

Webpack throws TypeError: Super expression must either be null or a function, not undefined when importing LESS file

I have the following in a file initialize.js:
import App from './components/App';
import './styles/application.less';
document.addEventListener('DOMContentLoaded', () => {
const app = new App();
app.start();
});
In webpack.config.js I have:
'use strict';
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const ProvidePlugin = webpack.ProvidePlugin;
const ModuleConcatenationPlugin = webpack.optimize.ModuleConcatenationPlugin;
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const extractLess = new ExtractTextPlugin({
filename: 'app.css',
});
const webpackCommon = {
entry: {
app: ['./app/initialize']
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader?presets[]=es2015'
}]
}, {
test: /\.hbs$/,
use: {
loader: 'handlebars-loader'
}
}, {
test: /\.less$/,
exclude: /node_modules/,
use: extractLess.extract({
use: [{
loader: 'css-loader'
}, {
loader: 'less-loader'
}],
// use style-loader in development
fallback: 'style-loader'
}),
}]
},
output: {
filename: 'app.js',
path: path.join(__dirname, './public'),
publicPath: '/'
},
plugins: [
extractLess,
new CopyWebpackPlugin([{
from: './app/assets/index.html',
to: './index.html'
}]),
new ProvidePlugin({
$: 'jquery',
_: 'underscore'
}),
new ModuleConcatenationPlugin(),
],
};
module.exports = merge(webpackCommon, {
devtool: '#inline-source-map',
devServer: {
contentBase: path.join(__dirname, 'public'),
compress: true,
port: 9000
}
});
I tried removing the the plugins and the contents of application.less, but I keep getting this error:
ERROR in ./node_modules/css-loader!./node_modules/less-loader/dist/cjs.js!./app/styles/application.less
Module build failed: TypeError: Super expression must either be null or a function, not undefined
at ...
# ./app/styles/application.less 4:14-127
# ./app/initialize.js
If I replace that LESS file with a CSS one and update the config it works fine, so I guess the problem has to do with less-loader.
I'm using Webpack 3.4.1, Style Loader 0.18.2, LESS Loader 4.0.5, Extract Text Webpack Plugin 3.0.0 and CSS Loader css-loader.
My bad, I didn't notice I was using an old less version. That was the culprit. Just updated it to 2.7.2 and the problem is gone.

Categories