shimming

在webpack 打包过程中,我们往往要做代码兼容或者打包过程的兼容。

比如我们之前使用的babel-polyfill 。

我们来讲一个例子,有一个第三方代码,如下。

export function ui () {
    $('body').css('background', 'green')
}

如果在index.js 中直接引入,是使用不了的。运行时,会报错。如下index.js 代码

import _ from 'lodash'
import $ from 'jquery'
import { ui } from './someUI'

ui()
const dom = $('<div>')
dom.html(_.join(['hello', 'world'], ' '))

$('body').append(dom)

因为一个模块就是一个作用域,模块之间的变量是隔离了的。

当第三方代码,是我们没法改的话。那么我们就需要使用垫片的形式解决这个问题 。

我们在webpack.config.js 中引入webpack,webpack 自己提供了一个插件 ProvidePlugin (https://webpack.js.org/plugins/provide-plugin/)

下面是webpack.config.js 配置

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const webpack = require('webpack')

module.exports = {
  mode: 'development',
  // devtool: "cheap-module-source-map",
  devServer: {
    contentBase: './bundle',
    open: true
  },
  entry: {
    main: './src/index.js'
  },
  module: {
    rules: [{
      test: /\.(png|jpg|gif)$/,
      use: {
        loader: 'url-loader',
        options: {
          name: '[name].[ext]',
          outputPath: 'imgs/',
          limit: 20480
        }
      }
    }, {
      test: /\.css$/i,
      use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
              // modules: true
            }
          },
          'postcss-loader'
      ],
    }, {
      test: /\.scss$/,
      use: ['style-loader', {
              loader: 'css-loader',
              options: {
                importLoaders: 2,
                // modules: true
              }
            },
            'sass-loader',
            'postcss-loader']
    }, {
      test: /\.(eot|ttf|svg)$/,
      use: {
        loader: 'file-loader'
      }
    }, {
      test: /\.js$/,
      exclude: /node_modules/,
      loader: 'babel-loader'
    }]
  },
  output: {
    filename: '[name].[contenthash].js',
    chunkFilename: '[name].chunk.[contenthash].js',
    path: path.resolve(__dirname, 'bundle')
  },
  optimization: {
    splitChunks: {
      chunks: 'all'
    },
      minimizer: [new OptimizeCSSAssetsPlugin({})]
  },
  plugins: [
      new HtmlWebpackPlugin({
        template: 'src/index.html'
      }),
      new CleanWebpackPlugin(),
      new MiniCssExtractPlugin({
        filename: '[name].css',
        chunkFilename: '[name].chunk.css'
      }),
      new webpack.ProvidePlugin({
          $: 'jquery'
      })
  ]
}

运行打包命令,之前的代码就可以正常运行了!

上面的配置,实际上是在打包的时候,代码中遇到$,会自动地引入node_module 中的jquery。然后把jquery 赋值给$。

当然,还有其他的配置形式

new webpack.ProvidePlugin({
  identifier: ['module1', 'property1'],
  // ...
});

idendifier 可以指代 module1.property1 属性。

下面介绍另一个东东,我们在每个index.js 顶部使用的this 都是指向这个模块,那么如果我们希望每个this 都指向window ,应该怎么做呢。这时候,我们需要一个Loader: imports-loader。

先安装

npm install --save-dev imports-loader

安装好了后,我们再对webpack 进行配置。

这是我们之前在对js 文件打包的时候都会使用到babel-loader

 {
      test: /\.js$/,
      exclude: /node_modules/,
      loader: 'babel-loader'
    }

下面,我们要同时使用imports-loader

{
      test: /\.js$/,
      exclude: /node_modules/,
      use: [
          {
              loader: 'babel-loader'
          }, {
              loader: 'imports-loader?this=>window'
          }
      ]
    }

Done!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值