I want to create two webpack chunks: app.js and vendor.js
Currently I have smth like:
entry = {
psw: DIR.src,
vendor: ["angular", "angular-ui-router", "angular-bootstrap"]
};
...
plugins.push(new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'))
(i.e. like here https://github.com/christianalfoni/react-webpack-cookbook/wiki/Split-app-and-vendors)
This works fine (At least it works and looks ok). However I want to generate that 'vendor' array automatically. Any ideas how that can be done?
Got it using SplitByPath plugin. It puts to separate bundle js as well as css, so its very nice to use. Dont know why it is referenced so rare.
config.plugins.push(new SplitByPathPlugin([{ name : 'vendor', path: [path.join(__dirname, 'node_modules'), path.join(__dirname, 'bower_components')]}]));
Related
I put all my images in a folder at the root of my project and I'm using them in the code that I write.
Howether there seems to be an error (ex : Cannot find module '../../../assets/Structure.png' or its corresponding type declarations because of:
import structure from "../../../assets/Structure.png";
). It still work when I do my yarn start but it seems to be a potential issue. Any idea of how to make it work without error? The issue seems to be with the '../'.
My project is like this :
src --> pages --> page1 --> index.tsx
assets --> image.png
The best practice is to create aliases to your folders which can be easily imported without any hassle.
Open babel.config.js situated in the root folder and add the following lines of settings
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
"module-resolver",
{
root: ["./src"],
extensions: ['.js', '.jsx', '.json', '.svg', '.png', '.jpg','.tsx','.ts'],
alias: {
"assets":"./src/assets"
}
}
]
]
};
Now you can easily import any assets like
assets/Structure.png without using ../../../ it will make your life easier..
You should similarly set up aliases for other common folders.
Make sure to completely re-run the application..
Cheers.
I am building wordpress plugin with react. I have added code splitting feature and worked perfectly.
Current case (1) with domain name : http://site_name (project configured on nginx)
Another case (2) with domain name: http://localhost:8888/site_name (project inside htdocs folder, apache)
For case 1:
module.exports = {
context: __dirname,
devtool: devMode ? 'inline-sourcemap' : false,
mode: devMode ? 'development' : 'production',
entry: {
builder: ['./src/form_builder/index.js'],
orders: './src/membership/orders.js', //ok
},
output: {
path: __dirname + '/dist/',
filename: '[name].build.js',
publicPath: `/wp-content/plugins/${plugin_name}/assets/js/dist/`
},
}
I have enqueued build js file builder.build.js and orders.build.js on wp-admin and other all split file also located in http://site_name/wp-content/plugins/plugin_name/assets/js/dist/ and these splitted file loaded on demand as expected.
For case 2 Problem : Issue seen when i tried to run same project on domain http://localhost:8888/site_name. Two build js builder.build.js and orders.build.js are loaded as expected but error occured for path location for splitted js file(i.e. 0.build.js, 1.build.js, *.build.js).
As i know already that path is being different as domain name is changed, is there way
As a quick fix i can do publicPath: ../wp-content/plugins/${plugin_name}/assets/js/dist/ to sort issue for http://localhost:8888/site_name but would create issue for http://site_name again.
Have anyone face the same issue, a little help would be really appreciated.
Thanks in advance.
In my webpack.config I have a cache prop. Does this make sure chunks are not regenerated anytime? I want to generate chunks from scratch every time.
Cache invalidation can be achieved by including a hash to the
filenames.
Assume you have the following configuration:
{
output: {
...
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].js',
},
},
Webpack would generate filenames like these based on it:
main.d587bbd6e38337f5accd.js
vendor.dc746a5db4ed650296e1.js
Learn more about webpack caching:
https://webpack.js.org/guides/caching
I'm transitioning a site to use Webpack, and I need a little help with configuration. I have a few pages written in Pug/Jade that are large and infrequently accessed (think Terms of Service or Privacy Policy). Most of my .jade files are Angular templates, so those are inlined in their components and it works well. These few files, however, I would like Webpack to compile into static HTML files served separately from the rest of the app. However, I would still like their file names to include a hash.
The basic idea I've come up with is like this:
In routes.ts:
$routeProvider.when('/_tos', templateUrl: require('./resources/terms-of-service.jade'))
In webpack.config.js's list of loaders:
{
test: /resources.*\.jade$/,
loaders: ['file?name=[name].[hash].html', 'pug-html']
}
I've tried that with various combinations of pug-loader, pug-html-loader (with and without the ?exports=false option), html-loader, extract-loader, extract-text-webpack-plugin, and file-loader, but everything I try has extra artifacts in the resulting .html file. E.g. it might start with module.exports =, or it might put \" everywhere in the file that should just have ".
Can anyone help?
Gah! I finally figured it out. I fundamentally misunderstood the way the list of loader works. I assumed only the first loader in the array that matched was used, but no, all loaders that match are used. (Though I'm still fuzzy on the details.) Here is a working configuration, where resources is the path to my "resources" directory:
loaders: [
{
test: /\.jade$/,
include: [resources],
loaders: ['file?name=[name].[hash].html', 'pug-html?exports=false']
},
{
test: /\.jade$/,
exclude: [resources],
loaders: ['pug-html?doctype=html']
}
]
I'm exploring the idea of using Webpack with Backbone.js.
I've followed the quick start guide and has a general idea of how Webpack works, but I'm unclear on how to load dependency library like jquery / backbone / underscore.
Should they be loaded externally with <script> or is this something Webpack can handle like RequireJS's shim?
According to the webpack doc: shimming modules, ProvidePlugin and externals seem to be related to this (so is bundle! loader somewhere) but I cannot figure out when to use which.
Thanks
It's both possible: You can include libraries with a <script> (i. e. to use a library from a CDN) or include them into the generated bundle.
If you load it via <script> tag, you can use the externals option to allow to write require(...) in your modules.
Example with library from CDN:
<script src="https://code.jquery.com/jquery-git2.min.js"></script>
// the artifial module "jquery" exports the global var "jQuery"
externals: { jquery: "jQuery" }
// inside any module
var $ = require("jquery");
Example with library included in bundle:
copy `jquery-git2.min.js` to your local filesystem
// make "jquery" resolve to your local copy of the library
// i. e. through the resolve.alias option
resolve: { alias: { jquery: "/path/to/jquery-git2.min.js" } }
// inside any module
var $ = require("jquery");
The ProvidePlugin can map modules to (free) variables. So you could define: "Every time I use the (free) variable xyz inside a module you (webpack) should set xyz to require("abc")."
Example without ProvidePlugin:
// You need to require underscore before you can use it
var _ = require("underscore");
_.size(...);
Example with ProvidePlugin:
plugins: [
new webpack.ProvidePlugin({
"_": "underscore"
})
]
// If you use "_", underscore is automatically required
_.size(...)
Summary:
Library from CDN: Use <script> tag and externals option
Library from filesystem: Include the library in the bundle.
(Maybe modify resolve options to find the library)
externals: Make global vars available as module
ProvidePlugin: Make modules available as free variables inside modules
Something cool to note is that if you use the ProvidePlugin in combination with the externals property it will allow you to have jQuery passed into your webpack module closure without having to explicitly require it. This can be useful for refactoring legacy code with a lot of different files referencing $.
//webpack.config.js
module.exports = {
entry: './index.js',
output: {
filename: '[name].js'
},
externals: {
jquery: 'jQuery'
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
})
]
};
now in index.js
console.log(typeof $ === 'function');
will have a compiled output with something like below passed into the webpackBootstrap closure:
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function($) {
console.log(typeof $ === 'function');
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)))
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
module.exports = jQuery;
/***/ }
/******/ ])
Therefore, you can see that $ is referencing the global/window jQuery from the CDN, but is being passed into the closure. I'm not sure if this is intended functionality or a lucky hack but it seems to work well for my use case.
I know this is an old post but thought it would be useful to mention that the webpack script loader may be useful in this case as well. From the webpack docs:
"script: Executes a JavaScript file once in global context (like in script tag), requires are not parsed."
http://webpack.github.io/docs/list-of-loaders.html
https://github.com/webpack/script-loader
I have found this particularly useful when migrating older build processes that concat JS vendor files and app files together. A word of warning is that the script loader seems only to work through overloading require() and doesn't work as far as I can tell by being specified within a webpack.config file. Although, many argue that overloading require is bad practice, it can be quite useful for concating vendor and app script in one bundle, and at the same time exposing JS Globals that don't have to be shimmed into addition webpack bundles. For example:
require('script!jquery-cookie/jquery.cookie');
require('script!history.js/scripts/bundled-uncompressed/html4+html5/jquery.history');
require('script!momentjs');
require('./scripts/main.js');
This would make $.cookie, History, and moment globally available inside and outside of this bundle, and bundle these vendor libs with the main.js script and all it's required files.
Also, useful with this technique is:
resolve: {
extensions: ["", ".js"],
modulesDirectories: ['node_modules', 'bower_components']
},
plugins: [
new webpack.ResolverPlugin(
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
)
]
which is using Bower, will look at the main file in each required libraries package.json. In the above example, History.js doesn't have a main file specified, so the path to the file is necessary.