My webpack.config.js contains the following part:
resolve: {
extensions: ['*', '.js', '.ts', '.tsx'],
modules: [
path.resolve(__dirname, "src"),
path.resolve(__dirname, "node_modules"),
],
alias: {
Design: path.resolve(__dirname, "src/Theme/Default")
}
},
There are 2 folders in this src/Theme folder: Default & Dark. I want to switch it in the alias setting when needed, it's not user controlled.
The import I use:
import Page from 'Design/Components/Page';
Webpack is working correctly with this but PhpStorm 2018.2 does not recognize this path as correct.
My PhpStorm settings for webpack are set to the path of my webpack.config.js.
More details and examples / logs can be found here: https://youtrack.jetbrains.com/issue/WI-43146
Webpack aliases resolving is not supported when editing TypeScript files, current TypeScript support implementation uses only the TypeScript resolution logic because we need to keep integration with the TypeScript language service (that is not aware of webpack aliases).
You can configure similar mappings in your tsconfig.json file, like:
"baseUrl": "",
"paths": {
"Design/*": ["src/Theme/Default/*"]
}
If you miss support for webpack resolving in TypeScript, please vote for WEB-29207
Related
I'm using Webpack to assemble dist directories with environment-specific configs (manifest.json) and file structures
My issue is that webpack wants me to have an empty src/index.js file
In certain environments, the compilation happens after I've assembled the /dist folder, zipped, and uploaded to their service.
Is there any way to avoid index.js and just run CopyWebpackPlugin?
I'm currently looking into using manifest.json or manifest.js as the entry for this build, since this file is the connection between an options HTML app, a browser content script, icon.png, etc
Both CleanWebpackPlugin and HtmlWebpackPlugin have given me tons of problems, and it seems that using loaders may be the correct, pure, synchronous way to go
My current inspiration uses a simple module.exports with arguments[0] source from the previous loader to easily transform the source
I did come up with a hack (un-maintanable) solution to delete the unused file afterwards, which may be of use to someone.
webpack.config.js
module.exports = {
name: 'manifest',
entry: {
manifest: './src/manifest.json',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'DELETED.js',
},
plugins: [
new CopyWebpackPlugin({
patterns: [
{from: './src/manifest.json'},
{from: './assets/images/icon.png'},
],
}),
new RemoveFilesWebpackPlugin({
before: {
log: false,
include: [
'dist',
],
},
after: {
log: false,
include: [
'dist/DELETED.js',
],
},
}),
],
mode: 'none',
}
The problem with this idea is that manifest.json is not being used to gather it's own assets -- the assets are declared in this bundler's config.
I have two additional webpack.config.js files for
generating an HTML options page using HtmlWebpackPlugin
bundling the main script
but as mentioned, maintenance requires digging in the build file, rather than just editing source and requiring relative paths
Im new to React development with Webpack having set up a boilerplate by following this tutorial article.
I get the jist of how webpack works and can follow along with the article but having trouble understanding how my particular webpack.config.js is creating the files and bundles that it does and how to modify these to achieve some custom function.
webpack.config.js
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader"
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
})
],
mode: 'development'
};
I understand that the rules object grabs all .js files (excluding those in node_modules) and compiles them to standard JS using babel. Then it grabs all the .html files and creates an html file including the bundle using html-loader. The HtmlWebPackPlugin is implemented here. Mode indicates to create a development version of the bundle.
My folder structure is as follows:
- /dist (generated by webpack)
- index.html
- main.js (webpack bundle)
- /src (created manually)
- /components
- components.js (react components)
- index.html
- index.js
- .babelrc
- package.json (npm init -y)
- webpack.config.js (manually configured)
Questions:
Webpack creates the /dist directory and the files contained in it. Where in the configuration is it indicated that this directory be named "dist" and the main bundle file be named main.js?
Where is it indicated that /dist be at the root of the project. Suppose I wanted the directory to be named foo and placed two levels up (../../foo/)
In webpack.config.js the "rules" object has keys defined as test to indicate which files types to bundle. test: /\.js$/, & test: /\.html$/ Is "test" an arbitrary value or a default webpack configuration key.
I was looking at these docs with regard to webpack configuration but the syntax was very different from what is shown here.
1 & 2:
you can set output config like this:
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
filename
name of output bundle file. default: main.js
path
location of save output files. default: /dist
to get root of project you have to use path!
import path:
var path = require('path');
and use like this:
path.resolve(__dirname, DIRECTORY_NAME)
3:
test is default webpack configuration key and its to specify that loader file type support like html-loader.
I am using:
react for page rendering.
typescript directly(without babel) transpiling tsx to ES5 for browsers
webpack to generate codes separately
babel-polyfill to be packaged in the vendor.js but not referenced by typescript codes
I want to package javascript libraries and my common codes into one vendor.js and generate separately [name].js files with [name].html (with template) referencing both vendor.js and [name].js for each [name].tsx (which conatins only a class definition [name] that extends React.Component<P,S>) with HtmlWebpackPlugin.
[name].tsx may import modules. Modules included in vendor.js cannot be included in [name].js, and the others must be normally included in [name].js
I have read the document form webpack official site and still have no idea how to do it.
I did find some guides that realize a multiple page website but having all libraries included in the separate [name].js files, which means the javascript libraries are redundantly included in every single [name].js and it is surely not expected.
And I found some guides about externals, but it can only be used on existing js files, not generated bundle files.
Here is my current webpack.config.js which supports only single page:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
module.exports = {
entry: {
"index.js": ['babel-polyfill', './src/index.tsx']
},
output: { filename: '[name]' },
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
})
],
module: {
rules: [{
test: /\.(ts|tsx)$/,
loader: 'ts-loader',
exclude: '/node_modules/'
}, {
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader'
},]
},
resolve: {
extensions: ['.webpack.js', '.web.js', '.ts', '.js', '.tsx']
},
devtool: "source-map"
}
Is there any way to have it support multiple pages as described?
I'm creating a javascript project. To create it I'm using gulp and babel.
My problem is that I can't develop my code over multiple file, so I'm search a solution to 'enable' importing. At the moment I'm trying to configure webpack.
The Gulp Task is this:
gulp.task('webpack', () => {
return webpack_stream(webpack_config)
.pipe(rename('webpack_code.js'))
.pipe(gulp.dest('.build/asset/webpack/'));
});
The webpack.config.js is this:
module.exports = {
entry: ['./src/asset/js/main.js'],
output: {
filename: 'bundle.js',
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.(js)$/,
exclude: /(node_modules)/,
loader: 'babel-loader',
query: {
presets: [
['env', 'stage-0',{ modules: false }],
],
},
},
],
},
resolveLoader: {
modules: ['./node_modules'],
},
resolve: {
modules: ['./node_modules'],
},
target: 'node',
};
My current error is this:
Error in plugin 'webpack-stream'
Message:
multi ./src/asset/js/main.js
Module not found: Error: Can't resolve 'babel-loader' in ...
What's wrong?
Another Question: What's I have to put as value of entry key? Only the entry point js file or the whole files of the project?
Thanks!!
What's wrong?
I'd guess that in your project, your Webpack instance is not finding the babel loader because of your config / environment specific issues.
I've had the exact same issue as you. Here are some troubleshooting steps for to check first:
See if babel-loader is actually installed. I know it is simple, but it can save you time.
Check which Webpack/Babel versions you're dealling with in your package.json file. I'm using Webpack 4 and Babel 8. Sounds like some newer versions doesn't accept this: use: 'babel' in your webpack.config file. You need to ensure that the -loader is being used as it follows: use: 'babel-loader'.
Reinstall your node_modules folder. Sometimes it works.
Another Question:
What's I have to put as value of entry key?
Only the entry point js file or the whole files of the project?
Accordingly to Webpack's docs:
The entry object is where webpack looks to start building the bundle. The context is an absolute string to the directory that contains the entry files. - Webpack Ref
Considering that, you should pass to the entry object, the path of a folder or a file that will be used to generate your final JS file with all your modules in it.
If you have nested files, that you don't import as modules, I think you'll have to head to the docs and see this specific case.
But if this files are nested and are being imported as modules, in your entry file/folder, they will be generated in the output file.
I know it's not much but following these steps, helped me to solve it. :)
I have a main React application and I create webpack bundled React libraries that can be loaded dynamically in the main app upon user request or as a result of some user actions.
I thought using SystemJS to dynamically load the librairies was the way to go but I can't find any pointers on the topic.
Here is my issue:
If I bundle the library with React dependencies, I can load the file with SystemJS but I'm getting this error:
invariant.js:44 Uncaught (in promise) Error: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded
This makes sense since React as been included in my bundle and is also part of the main App. So I thought excluding React from the lib will solve the problem. I added the "external" to my webpack config:
///////////////////////////////////////////////////////////
// Webpack config development
//
///////////////////////////////////////////////////////////
module.exports = {
devtool: 'source-map',
context: path.join(
__dirname, '../src/Extensions'),
entry: {
Extension: [
'./Extension/index.js'
]
},
output: {
path: path.resolve(__dirname, '../dist'),
filename: "[name].js",
libraryTarget: "umd",
library: "[name]"
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development'),
WEBPACK: true
}
}),
new webpack.ProvidePlugin({
'window.jQuery': 'jquery',
jQuery: 'jquery',
_: 'lodash',
$: 'jquery',
React: "React",
react: "React",
"window.react": "React",
"window.React": "React"
}),
new ProgressBarPlugin({
format: ' build [:bar] ' + chalk.green.bold(':percent') + ' (:elapsed seconds)',
clear: false
})
],
resolve: {
modules: [
path.resolve('./node_modules'),
],
extensions : ['.js', '.jsx', '.json']
},
resolveLoader: {
modules: ['node_modules']
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['transform-runtime']
}
}]
}
]
},
externals: {
"react": "React",
"react-dom": "ReactDOM"
}
}
But after doing so, loading the lib with SystemJS will output the following error:
ConfiguratorView.js:116 Uncaught (in promise) Error: (SystemJS) Unexpected token <
SyntaxError: Unexpected token <
at eval ()
Evaluating http://localhost:3000/React
Error loading http://localhost:3000/Extension.js
at eval ()
I understand SystemJS is attempting to load the React dependency at localhost:3000/React and from what I read this has to be configured with SystemJS.config({...}) but the question is how?? I read the SystemJS config documentation, but I haven't seen any example like so.
Am I the only one trying to dynamically load a React library? Is there a better approach? I want to have a flexible mechanism in place so unecessary libraries can be loaded on demand and do not bloat the main bundle.
Thanks for any pointer on that
Use a debundler or webpack as a browserify plugin to map the package names and locations to the SystemJS configuration files:
SystemJS is meant to work with any module definition specifications, and even a repository URL. This means when SystemJS encounters a require('module_name') or an import module_name, it doesn't know where to find the module called module_name. Would it be on npm? Or is it a custom repository? SystemJS can't know for sure.
So we'd need to provide a mapping of all packages' names and the location of their repository. Needless to say, doing this manually is impractical, so we must use another package manager, that manages packages from everywhere.
References
Build a React Application from First Principles - Modules + SystemJS
Stack update 2016: Future-proofing our javascript bundling with webpack 2 and rollup | Signal Agency Linz
How to bundle Syncfusion ReactJS components using webpack and browserify? | JavaScript | Syncfusion
shama/webpackify: Use webpack through a Browserify plugin
1egoman/debundle: A javascript debundler. Takes a Browserify or Webpack bundle and recreates the initial, pre-bundled source.