This is the 27th day of my participation in the August More Text Challenge

Before we introduced webpack compression merge code, Babel configuration, today we practice the use of global variables exposed in Webpack and webpack built-in plug-in;

Expose global variables

In the development process, we have a lot of time to expose some data or class library to the global, such as jQuery; Webpack also provides several ways to support this need.

1.1 expose – loader

Expose-loader can expose JQ to the whole world.

1.1.1 expose – loader installation

yarn add expose-loader
Copy the code

1.1.2 Modifying the Configuration File

  • test: require.resolve('jquery')When the resolution tojqueryModuleexpose-loaderExposure to the global
  • use: expose-loader? $Equivalent inliningimport $ from 'expose-loader? $! jquery'; ? $Is passed to theexpose-loaderRepresentsjqueryOnce exposed to the whole picture,$On behalf ofjqueryA reference to the
const path = require('path'); const HTMLWebpackPlugin = require('html-webpack-plugin'); const MiniCSSExtractPlugin = require('mini-css-extract-plugin'); / / out of the CSS file const OptimizeCSSAssetsWebpackPlugin = the require (' optimize - CSS - assets - webpack - plugin '); // const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin'); Module.exports = {entry: './ SRC /index.js', // mode: 'development', mode: 'production', output: {path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, devServer: { }, module: { rules: [/ / some ignored CFG loaders... {test: /. (HTM) | HTML $/, use: 'HTML - withimg - loader in the / / processing HTML img reference picture},+ {
+ test: require.resolve('jquery'),
+ use: 'expose-loader? $'
+}}, plugins: [], // Optimization: {}}Copy the code
  • After the exposure above, modify STHJS/A.js to test if the exposure is in effect
+ console.log($) // You can directly access the global $without importing
+ console.log(typeof $.ajax)
Copy the code

1.2 webpack.ProvidePlugin

Exposure to global is nothing more than the hope that each module can access, there is another way to solve this problem. Using webpack.ProvidePlugin to inject a module into each module, module can automatically access this module; ProvidePlugin is also one of the built-in plug-ins for WebPack that we talked about earlier, and there are a few more that we’ll talk about later;

1.2.1 importProvidePluginPlug-in and modify the configuration

  • inwebpack.config.jspluginsAdded in configurationnew webpack.ProvidePlugin({ $1: 'jquery',_: 'lodash' })
const path = require('path');

+ const webpack= require('webpack');module.exports = { entry: './src/index.js', // mode: 'development', mode: 'production', output: { path: Path.resolve (__dirname, 'dist'), filename: 'bundle.js'}, devServer: {// devServer configuration}, module: {rules: []}, plugins: [+ // Inject module: Key is the variable accessible in the module, value is the corresponding module
+ new webpack.ProvidePlugin({
+ $1: 'jquery',
+ _: 'lodash'
+})Minimizer: {minimizer: []}}Copy the code

1.2.2 Testing STHJS/A.js

Console. log($) // No import is required to directly access the global $+ console.log($1);
+ console.log(_);/ /... other code ignoredCopy the code
  • The effect is shown in figure

1.3 configuration externals

Another way to do this is through externals; The specific operation is through UMD, the required class library through script tag into the page;

Not only does this expose global variables, but it also has the advantage that these modules are not packaged and exported into bundles, so this is an important way to reduce the size of your code;

1.3.1 Inserting a class library into a document

Find a CDN connection to the library and add script tags to the HTML template to introduce the library. Take vUE as an example

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="root"></div>+ <div id="root-vue"></div>< p > this is a background of p tag < / p > < img SRC = ".. / img/miss - you PNG "Alt =" ">+ < script SRC = "https://cdn.bootcss.com/vue/2.6.10/vue.common.dev.js" > < / script >
</body>
</html>
Copy the code

1.3.2 Modifying a Configuration File

Add externals, externals: {vue: ‘vue’}, import vue from ‘vue’ to look for the global attribute window.vue

const path = require('path'); const webpack= require('webpack'); module.exports = { entry: './src/index.js', // mode: 'development', mode: 'production', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, devServer: { }, module: { rules: [], // Minimizer: {minimizer: []},+ // Configure externals
+ externals: {
+ vue: 'vue' // import vue from 'vue', it looks for window.vue
+}
}
Copy the code

1.3.3 Add vUE related codes in index.js

Import $from 'jquery' // expose $globally with expose-loader;+ import Vue from 'vue'

// ... other code ignored

+ / *!!!!!!!!!!!!!!! vue code start */
+ let components = {
+ template: `

{{content}}

`,
+ data () { + return { + content: 'root-vue' +} +}, + methods: { + handler () { + console.log('the components was clicked') +} +} +}; + + let vm = new Vue(components); + vm.$mount('#root-vue'); /* vue code end*/ Copy the code
  • The effect is shown in figure

Common webPack built-in plug-ins

2.1 webpack.DefinePlugin

The DefinePlugin plug-in can be configured to define some data for use in a module;

2.1.1 Modifying a Configuration File

const path = require('path'); const webpack= require('webpack'); module.exports = { entry: './src/index.js', // mode: 'development', mode: 'production', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, devServer: { }, module: { rules: [ ] }, plugins: [new HTMLWebpackPlugin({template: './ SRC /index.html', // The HTML file template to import output file hash: true, // Add hash filename to the imported JS file: 'index.html', // the name of the output HTML file (the plugin copies the template HTML to the output directory) minify: {// Compress the optimized output HTML file to configure removeAttributeQuotes: CollapseWhitespace: true // Collapse the CSS file new MiniCSSExtractPlugin({filename: 'CSS /main.[hash:5].css'}), // Insert module: new webpack.ProvidePlugin({$1: 'jquery', _: 'lodash' }),+ // Define data
+ new webpack.DefinePlugin({
+ // In this object key will become a variable and value will be a JS code expression
+ DEV: JSON.stringify('dev')
+})Minimizer: []}, // externals externals: {vue: 'Vue' // import Vue from 'Vue' will look for window.vue}}Copy the code

2.1.2 Create STHJS /b.js file and check DEV variable

+ console.log(DEV) // This DEV is the variable defined by webpack.defineplugin ()
Copy the code

If you look in your browser, you can see that the console prints ‘dev’; This ‘dev’ is the value of the dev variable we defined in webpack.defineplugin ();

2.2 webpack.CleanWebpackPlugin

We find that every time we run the NPM run build command, a new packaged file is generated. The previous file is useless, so WebPack provides a plugin to clean up the packaged content.

2.2.1 installation clean – webpack – the plugin

yarn add clean-webpack-plugin -D
Copy the code

2.2.2 Modifying the Configuration File

const path = require('path');

const webpack= require('webpack');

+ const { CleanWebpackPlugin } = require('clean-webpack-plugin');
+ const CopyWebpackPlugin = require('copy-webpack-plugin');


module.exports = {
  entry: './src/index.js',
  // mode: 'development',
  mode: 'production',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  devServer: {
    
  },
  module: {
    rules: [
      
    ]
  },
  plugins: [
    
+ // Empty the contents of the package
+ new CleanWebpackPlugin(),Minimizer: []}, // externals externals: {vue: 'Vue' // import Vue from 'Vue' will look for window.vue}}Copy the code
  • Then modify the file executionnpm run buildCommand, we will find that the previously packaged files and deleted; After this, each time the package is executed, the previous file is cleared and a new package file is output.

2.3 copy – webpack – the plugin

The copy-webpack-plugin is often used in projects where files need to be copied from the source file directory to the output directory.

2.3.1 installed copy – webpack – the plugin

yarn add copy-webpack-plugin -D
Copy the code

2.3.2 Modifying a Configuration File

We create a doc directory under SRC and a reademe.md file.

  • Copy the contents of a file: Receives an array of objects, from representing the copied directory or file, to representing the output directory;

  • new CopyWebpackPlugin([{from: './src/doc',to: path.resolve(__dirname, './dist/doc')}])

const path = require('path');

const webpack= require('webpack');

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
+ const CopyWebpackPlugin = require('copy-webpack-plugin');


module.exports = {
  entry: './src/index.js',
  // mode: 'development',
  mode: 'production',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  devServer: {
    
  },
  module: {
    rules: [
     
    ]
  },
  plugins: [
    
+ new CopyWebpackPlugin([
+ {
+ from: './src/doc',
+ to: path.resolve(__dirname, './dist/doc')
+}
+])}, // externals externals: {vue: 'vue' // import vue from 'vue'Copy the code
  • src/doc/reaeme.md
# When you pass by my world ## You are always in love ## Are once young is paper short love longCopy the code
  • The effect is shown in figure

2.4 webpack.BannerPlugin

Some scenarios require some information to be generated in the code, such as agreement, copyright, author, etc.

const path = require('path');

const webpack= require('webpack');



module.exports = {
  entry: './src/index.js',
  // mode: 'development',
  mode: 'production',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  devServer: {
   
  },
  module: {
    rules: [
     
    ]
  },
  plugins: [
   
+ // Prints the necessary information in the packaged code
+ new webpack.bannerPlugin (' Send your first wish, tie your middle edge, enjoy your lower fortune; Choose a high place to stand, find a flat place to live, want to go wide ')Minimizer: []}, // externals externals: {vue: 'Vue' // import Vue from 'Vue' will look for window.vue}}Copy the code
  • The effect is shown in figure