why doesn't webpack support static field?
When i try
export class Game {
#lasttime = 0;
#FRAME_DURATION = 1000 / 144;
I get an error
Module parse failed: Unexpected character '#' (2:4)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders.
What is the problem?
const path = require('path');
const HTMLPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'js/main.js',
path: path.resolve(__dirname, 'dist'),
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
},
plugins: [
new HTMLPlugin({
template: './src/index.html'
})
],
};
https://webpack.js.org/guides/getting-started/#modules:
Note that webpack will not alter any code other than import and export statements. If you are using other ES2015 features, make sure to use a transpiler such as Babel or Bublé via webpack's loader system.
You need to configure babel-loader yourself, see https://webpack.js.org/loaders/babel-loader/#root
Related
I have a question for you - how is it possible to implement multi-file compilation while preserving the tree of folders and documents, while not writing each file into entry in this way
entry: {
index:'./src/index.ts',
'bot/main':'./src/bot/main.ts'
}
But at the same time, the files had their names and their position, as before compilation in js, only instead of the src folder, they were in the dist folder?
My current config webpack.config.js
const path = require('path')
const nodeExternals = require('webpack-node-externals')
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin')
module.exports = {
context: __dirname,
entry: {
index:'./src/index.ts',
'bot/main':'./src/bot/main.ts'
},
externals: [nodeExternals()],
module: {
rules: [
{
exclude: /node_modules/,
test: /.ts$/,
use: {
loader: 'ts-loader'
}
}
]
},
node: {
__dirname: false
},
resolve: {
extensions: ['.ts', '.js'],
plugins: [
new TsconfigPathsPlugin({
baseUrl: './src'
})
]
},
output: {
filename: '[name]js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/'
},
target: 'node'
}
And when building in production mode, all this was compiled into one file, taking into account all URLs, imports, etc.
Is it even possible?
Webpack itself won't do that for you. You will need to write litter helper function to achieve this. The basic idea is to crawl the directory, find all the files and then provide them to Webpack:
const path = require('path');
const glob = require('glob');
const extension = 'ts';
// Recursively find all the `.ts` files inside src folder.
const matchedFiles = glob.sync(`./src/**/*.${extension}`, {
nodir: true
});
const entry = {};
matchedFiles.forEach((file) => {
const SRC_FOLDER = path.join(__dirname, 'src');
const ABS_PATH = path.join(__dirname, file);
// Generates relative file paths like `src/test/file.ts`
const relativeFile = path.relative(SRC_FOLDER, ABS_PATH);
// fileKey is relative filename without extension.
// E.g. `src/test/file.ts` becomes `src/test/file`
const fileKey = path.join(path.dirname(relativeFile), path.basename(relativeFile, extension));
entry[fileKey] = relativeFile;
});
module.exports = {
context: __dirname,
// Use the entry object generated above.
entry,
// ... rest of the configuration
};
When building with webpack 5, I get the error:
[webpack-cli] Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.devtool should match pattern "^(inline-|hidden-|eval-)?(nosources-)?(cheap-(module-)?)?source-map$".
BREAKING CHANGE since webpack 5: The devtool option is more strict.
Please strictly follow the order of the keywords in the pattern.
In my webpack.config.js however, I have the setting:
devtool: 'eval-cheap-source-map',
Ive also tried eval as value which also does not work, although this website (https://webpack.js.org/configuration/devtool/) seems to indicate that it should.
I do not understand, what is going wrong here?
edit:
my webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/app.js',
plugins: [
new HtmlWebpackPlugin({
title: 'MyApp',
}),
],
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'var',
library: 'MyApp'
},
resolve:{
alias:{
EVENTS: path.resolve(__dirname, "src/events"),
MODELS: path.resolve(__dirname, "src/models"),
GUI: path.resolve(__dirname, "src/gui"),
HELPER: path.resolve(__dirname, "src/helper")
}
},
devtool: 'eval-cheap-source-map',
devServer: {
watchContentBase: true,
contentBase: path.resolve(__dirname, 'dist'),
port: 9000
},
module: {
rules: [
{
test:/\.css$/,
use:['style-loader', 'css-loader']
}
]
},
}
my buildscript is webpack src/app.js -d --watch
Remove the -d parameter from your build script. -d stands for devtool, but it is not followed by a parameter value in your command.
I am trying to figure out webpack. I want to bundle a css and js file while also minimizing them at the same time. I am using optimize-css-assets-webpack-plugin and got it to work together with mini-css-extract-plugin. But, when bundling css into js with style-loader, the css is no longer minified. Does anyone have any ideas on what I can do to make this work?
Index js file:
import './styles.css';
// some js
Webpack config:
const path = require('path');
const OptimizeCss = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const bundle = {
entry: './src/index.js',
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, './'),
},
module: {
rules: [
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader'
],
},
],
},
optimization: {
minimizer: [
new OptimizeCss(),
new TerserPlugin()
]
},
mode: 'production',
watch: false
}
module.exports = bundle;
Edit: I am using webpack version 4.39.3
I'm working on Arrow project and I'm in phase to create the Bundle file using Webpack.
I grouped my modules in a folder. and for each folder I have index.js where I export all modules.
Also, I have global index.js that imports all index.js like this :
import * as Has from "./scripts/array/has"
import * as Math from "./scripts/array/math"
import * as Arrow from "./scripts/array"
export { Has, Math, Arrow }
Now, I want to create my bundle from this global index.js .
My Webpack configuration looks like :
const path = require("path")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
module.exports = {
mode: "development",
entry: {
arrow: "./src/1.x.x/index",
},
plugins: [
new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),
],
devtool: 'inline-source-map',
devServer: {
contentBase: './build',
},
output: {
filename: "[name]-alpha.js",
path: path.resolve(__dirname, 'build'),
},
optimization: {
splitChunks: {
chunks: 'all',
},
},
}
The Issue is when I try to import my functions from the build the functions do not appear in the Autocomplete and I received errors that these functions are undefined!
I have just ___esModule :
import { __esModule } from "./arrow-alpha"
I want to let developers use and import the functions like the example
import {omit} from "arrow" // arrow is the bundled file
const frameworks = ["react", "vue", "ember", "angular"];
const withoutAngular = omit(frameworks,"angular");
console.log(withoutAngular); // ["react", "vue", "ember"]
I blocked in this step for days and I could not figure out the issue.
It sounds like you are looking to export your code as library with webpack. In order to do so, you should export your library module as umd which can work for backend/client side so IDE can also understand what you export. Just add following configuration in your webpack.config.js:
output: {
libraryTarget: 'umd', // style for your library
library: 'yourLibName', // if you keen to have a name for library
// ...
},
NOTE: this only works if you pass to webpack a cjs style code, otherwise it will convert to harmony module which you can't export accordingly (such as esm module)
In order to make sure babel would convert your esm module to commonjs, you have to set modules to commonjs like this:
babel.config.js or .babelrc
[
"#babel/preset-env",
{
"modules": "commonjs",
}
]
Adding below Configuration. Will eject your final bundle to be accessed as Window.Arrow on adding script to index.html page
output: {
filename: "[name]-alpha.js",
path: path.resolve(__dirname, 'build'),
library: 'Arrow',
libraryTarget: 'var'
},
and your index.js page inside src folder to be as
module.exports = require('./scripts/array');
I want to set up an Angular 1.x app from scratch using webpack 2.
I am having trouble finding the best configuration for webpack.config, with optimal entry and output for production (meaning, all code, style and templating minified and gziped with no code repetition).
My main problem is how to set up webpack.config so that it recognizes all partials within the folder structure of my project, like these:
My current config file, for reference (which can't see subfolders):
var HtmlWebpackPlugin = require( 'html-webpack-plugin' );
var ExtractTextPlugin = require( 'extract-text-webpack-plugin' );
var path = require( 'path' );
module.exports = {
devServer: {
compress: true,
contentBase: path.join( __dirname, '/dist' ),
open: true,
port: 9000,
stats: 'errors-only'
},
entry: './src/app.js',
output: {
path: path.join( __dirname, '/dist' ),
filename: 'app.bundle.js'
},
module: {
rules: [ {
test: /\.scss$/,
use: ExtractTextPlugin.extract( {
fallback: 'style-loader',
use: [
'css-loader',
'sass-loader'
],
publicPath: '/dist'
} )
} ]
},
plugins: [
new HtmlWebpackPlugin( {
hash: true,
minify: { collapseWhitespace: true },
template: './src/index.html',
title: 'Prov'
} ),
new ExtractTextPlugin( {
filename: 'main.css',
allChunks: true
} )
]
};
Note that this isn't an exhaustive solution, as there are many optimizations one can make in the frontend, and I've kept the code snippets fairly short.
With webpack, there are a few routes that you can take to include partials into your app.js.
Solution 1
You can import/require your partials within app.js as such:
app.js
var angular = require('angular');
var proverbList = require('./proverb/list/proverb.list');
// require other components
// set up your app as normal
This allows the app.bundle.js to include your component js files in the main bundle. You can also use html-loader to include templates in the final bundle.
This isn't ideal, as all it does is create a large bundle.js (which doesn't leverage multiple downloads with http2 nor does it allow loading of components/files when the user explicitly requires it).
Solution 2
Importing partials as separate entry files into your webpack bundle:
webpack.config.js
const globby = require('globby');
const sourceDir = 'src';
var webpackentry = {
app: `${__dirname}/src/app.js`
};
const glob = globby.sync(`${__dirname}/${sourceDir}/**/*.js`)
.map((file)=>{
let name = file.split('/').pop().replace('.js', '');
webpackentry[name] = file;
});
const config = {
entry: webpackentry,
...
}
The second solution is unorthodox but it can be useful if you wanted to split all your partials as <script> tags in your html (for example if your company/team uses that as a means to include your directive/components/controllers), or if you have an app-2.bundle.js.
Solution 3
Use CommonsChunkPlugin:
webpack.config.js
let webpackentry = {
vendor: [
'module1',
'module2',
'module3',
]
}
...
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['vendor'] //... add other modules
})
]
CommonsChunkPlugin allows webpack to scrawl through your entry files and discern common modules that are shared among them. This means that even if you are importing module1 in different files, they will be compiled only once in your final bundle.