Webpack - Using Script Loader in webpack.config.json - javascript

I am just starting to dip my toes into the world of webpack. I am using the awesome Vue.js with vueify, so therefore my modules are ES6.
One difficulty I am having is loading some 3rd party jQuery plugins. I am using the ProvidePlugin to load jQuery - which works fine.
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
I then have a directory called plugins containing misc jQuery plugins. My understanding is the script loader just loads these into the bundled file as strings, and they are eval-ed when the bundle loads. These scripts can then be used as if they were loaded in a regular script tag (i.e., no import needed).
But I just cant get any of the plugins to work. Below is my loaders array. What I am doing wrong (or not doing)?
loaders: [
// process *.vue files using vue-loader
{
test: /\.vue$/,
loader: 'vue'
},
// process *.js files using babel-loader
// the exclude pattern is important so that we don't
// apply babel transform to all the dependencies!
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
},
{
test: /plugins\.js$/,
loader: 'script-loader' #tried script too
}
]

I can sympathize with the difficulty of getting jQuery plugins to work with webpack. While I don't have a solution to this specific configuration, I have found it useful to use a cdn to keep development rolling along until further troubleshooting can be done. Below is an example.
In your .html template file:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
In index.js or whatever your main entry point is:
import $ from 'jquery'
In your webpack config:
externals: {
jquery: 'jQuery'
}
Since this approach involves direct use of script tags it may work more reliably, while temporarily sacrificing opportunities for optimization and bundling.

new webpack.ProvidePlugin({
'React': path.resolve(__dirname, "node_modules/react/react"),
'ReactDOM': path.resolve(__dirname, "node_modules/react-dom/dist/react-dom"),
"jQuery": path.resolve(__dirname, "node_modules/jquery/dist/jquery"),
"$": path.resolve(__dirname, "node_modules/jquery/dist/jquery")
})
resolve you lib path

Related

How to Webpack a multiple page (tsx) website with separate js files?

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?

Using Bootstrap with Webpack

I have an app that uses Webpack. I'm new to Webpack and trying to learn how to use it effectively. Specifically, I'm trying to import Bootstrap with Font Awesome into my project. I found this SO post, however, I am still unable to use Bootstrap. I'm not sure if it's out-of-date, or if I'm misunderstanding something.
I tried loading Bootstrap and Font Awesome via the url-loader. I was referencing the following URLs:
https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css
https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css
I also tried using loading Bootstrap and Font Awesome via NPM and then referencing it in my entry file like this:
require('bootstrap');
require('font-awesome');
It seems like this should be part of a commonly used template. However, I'm not finding one. How do I use Bootstrap and Font Awesome with Webpack?
However, I've come up short with that approach as well.
I have created a simple example on GitHub. Webpack 2 and Bootstrap 3 are used.
Install dependency npm install jquery bootstrap
index.js
require('bootstrap');
require('bootstrap/dist/css/bootstrap.css');
require('font-awesome/css/font-awesome.css'); //Optional. The question author uses this package.
webpack
const webpack = require('webpack');
const path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: path.resolve(__dirname, "index.js"),
output: {
path: path.resolve(__dirname, 'dist'),
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.woff2?$|\.ttf$|\.eot$|\.svg$/,
use: [{
loader: "file-loader"
}]
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}
]
},
plugins: [
new ExtractTextPlugin('bundle.styles.css'),
new webpack.ProvidePlugin({
// inject ES5 modules as global vars
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
]
};
index.html
<link rel="stylesheet" type="text/css" href="/dist/bundle.styles.css">
<script type="text/javascript" src="/dist/bundle.js"></script>
You can use HtmlWebpackPlugin if don't want to insert bundle.styles.css and bundle.js manually.
if you are not generating your base HTML file dynamically then you can symply include a <link> tag in your base html's head section (means same base html file everywhere)
and if you want to use it using webpack then along with url-loader you need to use either style-loader and css-loader (if you want to insert the style as style tag in head witch is probabbly not the case)
or you can use webpack's extract to text plugin to load as a different file and insert it using html link tag
for reference you can use this open source project's configration file
webpack production config
and
webpack developement config
edit: link update

Webpack: Style tag per required css file

I want to have one tag per required .css file.
I want it like that because I want to connect chrome dev-tools workspace feature to my src folder, so I could edit my css files directly from the browser.
Here's my research on loaders:
style-loader only loads into style tags
style-loader/url + file-loader doesn't work (I tried the README example)
extract-text-webpack-plugin seems to only generate ONE bundle per ALL css files with default configuration.
The Modify Files section in extract-text-webpack-plugin suggests that with multiple entry points, it's possible to generate multiple bundles, so I thought that it might be possible to abuse this feature to get the behaviour I want.
This is of course for development and I don't intend on serving my css this way.
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}
]
},
plugins: [
new ExtractTextPlugin('[name].css'),
new HtmlWebpackPlugin({
template: 'path/to/your/index.html',
})
],
resolve: {
extensions: [ '.js', '.css' ]
}
Then in your js files, do import path/to/your/stylesheet.css; for each stylesheet you want webpack to extract.
Note: you need to install html-webpack-plugin and add it like above so that webpack can insert references to your stylesheets. Click HERE to learn more about the options for HtmlWebpackPlugin

let webpack output individual compiled files besides bundle

I'm using the webpack loader ts-loader to compile typescript sourcefiles into a javascript bundle. Now I would like the individualy compiled javascript files also to be saved, as well as the bundle! I'm familliar with writing a very simple webpack plugin, but I'm not sure as to how to go about implementing this. That is: I don't know which events triggered by webpack to listen to and where to find the relevant data. Any help?
As I commented, you can't use webpack compiled individual files. It might break with Uncaught ReferenceError: __webpack_require__ is not defined.
It's better write your own loader or ask the ts-loader to provide the option to retain the transpiled source.
Or i have written a loader which can save the typescript compiled files as individual files.
you can use this loader second loader or post-loader as shown below
as a second loader:
module: {
loaders: [{
test: /\.ts?$/,
loaders: ['scatter-loader', 'ts-loader']
}]
}
or as a post-loader
module: {
loaders: [{
test: /\.ts?$/,
loaders: ['ts-loader']
}],
postLoader: [{
test: /\.ts?$/,
loaders: ['scatter-loader']
}]
}
Note: scatter-loader work is in progress.

Webpack angularjs copy angularjs templates but don't include in javascript bundle

What I'm trying to do is configure webpack in a way that would copy all the partial html templates that are required in angular 1.x directives etc. into a separate folder (just like the file-loader does for assets referenced from css). I don't want the partial htmls to be included in my javascript bundle but rather have all of them in one folder with hashed names.
I tried configuring the file-loader to do it but when I run webpack in watch mode it also copies the those html in the dist folder again to it appending a new hash and essentially makes an infinite loop as every new html that shows up in that folder is copied, thus a new html appears and again and again. I tried to set an exclude matching pattern for that loader but webpack was still running constantly watching over that folder.
Here is the excerpt of my webpack.config.js file:
module: {
loaders: [
test: /\.html$/,
exclude: /bundle\/templates/,
loader: `file-loader?name=bundle/templates/[name]-[hash].[ext]
]
}
is there a loader that would help me do what I want without resorting to hacks?
Ok I have found the answer. The problem wasn't the file-loader which is configured correctly like this even without the exclude. What caused the infinite loop was a dynamic require that created a regex that matched those copied assets too... So by setting a proper context for this dynamic require the problem was resolved.
In the webpack.config file you can use the same way like this in the loader section.
{
test: /\.html$/,
exclude: path.resolve(__dirname, 'index.html'),
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'views/'
}
},
And in the plugins section of the webpack.config file
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
inject: true
}),
new ExtractTextPlugin('bundle.css')
]
This will copy all the htmls and will be refered from the index.html

Categories

Resources