React+Webpack实现第三方库和本身写的代码分开打包

背景

在项目中用webpack打包时,一般会将本身写的业务逻辑代码和第三方库的js文件一块儿打包成一个js文件,这样的话这个文件就会很大,对项目的运行速率影响很大。并且,咱们在打包时每次都会将第三方库文件从新打包一次,可是每每这样是没有必要的,由于第三方每每是不会发生很大改变的,只是可能会须要升级一下。因此在这里,将第三方库文件和本身写的js文件分开打包仍是颇有必要的,这里总结一下目前用得最多的两种方法。css

利用react官网的脚手架建立一个例子

按照下面几个步骤就能够建立一个小demohtml

  • npm add create-react-app
  • create-react-app myapp
  • cd myapp
  • npm start

运行完这几步后,恭喜你成功建立了一个react小例子,接下来须要作的就是如何使用webpack来打包这个demo。node

在myapp下建立webpack.base.config.js文件

在文件中写基本的配置以下:react

const path = require('path')
const webpack = require('webpack')

function resolve(relatedPath) {
  return path.join(__dirname, relatedPath)
}
module.exports = {
  entry: {
    index: resolve('../myapp/src/index.js')
  },
  output: {
    path: resolve('../myapp/dist'),
    filename: '[name].[hash:4].js',
    chunkFilename: 'chunks/[name].[hash:4].js',
  },
  resolveLoader: {
    moduleExtensions: ['-loader']
  },
  module: {
    rules: [
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          presets: ['react', 'es2015', 'stage-0']
        }
      },
      {
        test: /\.css/,
        loader: 'css'
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url',
        options: {
          limit: 8192,
          name: 'img/[name].[hash:4].[ext]'
        }
      },
      {
        test: /\.html$/,  //静态资源
        loader: 'html',
      }
    ],
  }

}

package.json文件的配置内容以下:webpack

"dependencies": {
    "react": "^16.5.0",
    "react-dom": "^16.5.0",
    "webpack": "~3.10.0"
  },
  "devDependencies": {
    "babel-core": "~6.26.0",
    "babel-eslint": "~8.2.1",
    "babel-loader": "~7.1.2",
    "babel-plugin-import": "^1.8.0",
    "babel-plugin-transform-decorators-legacy": "~1.3.4",
    "babel-plugin-transform-runtime": "~6.23.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "css-loader": "~0.28.9",
    "url-loader": "~0.6.2"
  }

使用npm install或yarn install就能够将须要的工具都加载好web

修改package.json中scripts中的内容

在上面的package.json文件中将build的内容改为npm

"build": "webpack --config webpack.base.config.js"

而后npm build和yarn build都可,这样就使用webpack打包了react官网的例子json

分析

首先看一下这个小demo的文件目录
图片描述babel

本身的业务逻辑是src中的文件,而第三方库是在node_modules中,咱们就须要将这两个分开打包,由于node-modules相对于本身的js文件是很大的,下面介绍一下两种分开打包的方法。app

使用CommonsChunkPlugin

这个方法会使咱们的第三方库文件在打包的时候和本身的业务逻辑分开,也很简单,主要是路径要写对,就像下面这样在你的配置文件中添加便可

plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendors',
      filename: '[name].[hash:4].js'//生成的vendors文件就是以这样的形式命名
    }),

  ]

在webpack.base.config.js的入口文件中增长

vendors: ['react', "react-dom"]//指的是想将什么第三方文件库进行分开打包

这样就能够实现分开打包的功能了,是否是很简单,固然简单一点,必然也是有缺点的,至于缺点是啥,就接着往下看咯!

使用DllPlugin

这个插件比CommonsChunkPlugin更复杂一些,固然也好一些,并且要配合.DllReferencePlugin使用,使用DllPlugin须要单首创建一个配置文件,咱们叫它webpack.dll.config.js文件,在这个文件中咱们须要放置这些内容:

const webpack = require('webpack')
const path = require('path')

function resolve(relatedPath) {
  return path.join(__dirname, relatedPath)
}

module.exports = {
  entry: {
    vendors: ['react', "react-dom"]//须要打包的第三方库文件
  },

  output: {
    filename: '[name].[chunkhash:4].js',//生成的文件名
    path: resolve('../myapp/dist'),//生成的文件存放的路径
    library: '[name]_[chunkhash:4]'//决定了manifest中的格式
  },

  plugins: [
    new webpack.DllPlugin({
      path: resolve('../myapp/dist/manifest.json'),
      name: '[name]_[chunkhash:4]',//生成的第三方库文件, 要和上面的library一致
      context:__dirname
    }),
  ],
}

在webpack.dll.config.js放置这些事后还要在webpack.base.config.js中放置它的搭档插件

plugins: [
    new webpack.DllReferencePlugin({
      context: __dirname,//上下文关系
      manifest: require('./dist/manifest.json')//生成的索引表
    }),
  ],

完成这两步后要给package.json文件中scripts中的内容添加一条

"webpack": "webpack --config webpack.dll.config.js"

而后运行yarn webpack,再运行yarn build就能够看到生成以下的文件目录
图片描述

生成了三个文件,本身写的代码打包后的是index.js,第三方是vendors.js,而manifest则是这两个的桥梁,是用来联系index.js和vendors.js的。
图片描述

点开文件夹你会发现js文件会变小不少,而vendors.js会大不少,这样就是分离成功了。

总结

这两个插件均可以实分开打包的功能,前者较后者比较简单,后者比前者更高效,高效体如今后者是在编译的过程就将二者分开了,便可以只编译本身写的代码,也能够调用vendors.js中的第三方库;而前者是在打包的时候将二者分开,这样看的话仍是后者更加高效。

相关文章
相关标签/搜索