全国服务热线:4008-888-888

行业新闻

小程序制作要多少钱_详解Webpack抽离第三方类库以

mon解决方案       mon解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前端构建场景有两种,一种是单页面构建,另一种是多入口构建多页面应用程序(我视野比较小,目前就知道这两种),下面我们针对这两种场景总结了几种抽离第三方类库以及公共文件的解决方案。

如果有哪些地方优化不周到,请指点一二,另外求关注求星星,么么哒

单页面构建:

常规配置

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
 mode: "development",
 entry: {
 app: './app.js'
 output: {
 path: path.resolve(__dirname, './build/'),
 filename: "bundle-[chunkhash:8].js"
 devtool: "source-map",
 module: {
 rules: [
 test: /\.js$/,
 use: {
 loader: 'babel-loader',
 exclude: /node_modules/
 test: /\.css$/,
 use: [
 MiniCssExtractPlugin.loader,
 'css-loader'
 exclude: /node_modules/
 test: /\.less$/,
 use: [
 MiniCssExtractPlugin.loader,
 'css-loader', // translates CSS into CommonJS
 'less-loader', // compiles Less to CSS
 exclude: /node_modules/
 test: /\.(jpe g|png|gif|svg)$/i,
 use: [{
 loader: 'file-loader',
 options: {
 limit: 1024,
 plugins: [
 new MiniCssExtractPlugin({
 filename: "[name].[chunkhash:8].css",
 chunkFilename: "[id].[chunkhash:8].css"
 new HtmlWebpackPlugin({
 title: 'webpack',
 ',
 chunks: ['app']
 new CleanWebpackPlugin()
}

在脚本种我们常规写法是这样的

require('./main-less.less');
require('./main-css.css');
const ReactDOM = require('react-dom');
const React = require('react');
import Main from './main.js';
// /**
// * 引入 scope hisiting test
// */
// import B from './ScopeHisitingTest/b';
ReactDOM.render(
 Main / ,
 document.getElementById('app')
)

我们看下构建输出结果

现在我们看到这个应该思考三个问题

1.脚本部分,难道每个页面都要写一边import React ReactDOM 吗

2.构建体积能不能再缩小一点

3.构建速度能不能在快一点

以上三个问题都会在开发过程中耽误开发效率,我们开始处理这三个问题

方案1

html全局引用第三方类库,比如React,因为React源码中将React挂在到了window上,这么做解决了什么呢,脚本里面我们不用在每一个页面中引用第三方类库了,我们看下代码

 !DOCTYPE html 
 html 
 head 
 meta charset="UTF-8" 
 /head 
 body 
 div id='app' /div 
 script crossorigin src="/react.development.js" /script 
 script crossorigin src="react-/react-dom.development.js" /script 
 /body 
 /html 

好了解决了脚本部分不用每个页面都需要import一次了

构建体积怎么减小呢

这里我们可以借助webpack插件,下面我们上代码

 externals: {
 'react': 'react',
 'react-dom': 'react-dom'
 },

我们将两个第三方类库打包的时候不依赖进去就可以啦,我们看下打包效果

可以明显的看到,采用这种用法之后会有一个问题就是,我们在脚本里面就不能在引用第三方类库了,不然打包进去,external会找不到这个第三方导致报错,直接用就好了,我们毕竟要解决的就是这个问题嘛。

以上就是第一种解决方案。

第二种

第二种方式采用将第三方类库打包到指定的dll中,通过webpack构建应用时引用

涉及两个Plugin,分别是DllReferencePlugin,DllPlugin

首先创建一个专门针对dll的webpack配置文件

const webpack = require('webpack');
const path = require('path');
module.exports = {
 entry: {
 react: [
 'react',
 'react-dom'
 output: {
 filename: '[name].dll.js',
 path: path.resolve(__dirname, './distDll/dll/'),
 library: '[name]_dll_[hash]'
 plugins: [
 new webpack.DllPlugin({
 name: '[name]_dll_[hash]',
 context: __dirname,
 path: path.join(__dirname, 'distDll/dll', '[name].manifest.json')
}

然后执行这个webpack,生成dll以及描述模块运行依赖的manifest.json,我们应用的webpack需要引用这个dll

 new webpack.DllReferencePlugin({
 context: __dirname,
 manifest: require('./distDll/dll/react.manifest.json')
 }),

到这里就结束了吗,并不是,我们执行下webpack会发现,React找不到了,我们首先考虑到什么,难道是external的问题吗,你会发现跟它一点关系没有,难道我们每次写还要导入第三方类库吗,解决方案

ProvidePlugin

 new webpack.ProvidePlugin({
 'React': 'react',
 'ReactDOM': 'react-dom'
 })

这样就解决了这个问题,我们看下构建效果

同样也达到了我们的目的

方案三

mon部分的用法是一样的,我们就跟多页面一起具体了。

多页面解决方案

基本配置

const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
 mode: 'development',
 entry: {
 app1: './app1.js',
 app2: './app2.js'
 output: {
 path: path.resolve(__dirname, './build/'),
 filename: "[name]-[chunkhash].js"
 devtool: "source-map",
 module: {
 rules: [
 test: /\.less$/,
 use: [
 MiniCssExtractPlugin.loader,
 loader: 'css-loader',
 'less-loader',
 exclude: /node_modules/
 test: /\.js$/,
 use: [
 'cache-loader',
 loader: 'babel-loader',
 exclude: /node_modules/
 plugins: [
 new MiniCssExtractPlugin({
 filename: '[name].[hash:5].css',
 new CleanWebpackPlugin(),
 new HtmlWebpackPlugin({
 title: 'index1',
 ',
 ',
 chunks: ['app1', 'common'],
 // hash: true
 new HtmlWebpackPlugin({
 title: 'index2',
 ',
 ',
 chunks: ['app2', 'common'],
 // hash: true
 new webpack.HashedModuleIdsPlugin(),
}

打包效果

问题很明显,速度慢,体积过大,这里还有个问题就是,mon部分的问题,这里我们就不讨论脚本import 第三方的问题了,上面有解决方案了。

optimization: {
 runtimeChunk: {
 "name": "manifest"
 splitChunks: {
 chunks: 'all',
 cacheGrou凡科抠图: {
 default: false,
 vendors: false,
 common: {
 test: /\.(s*)js$/,
 chunks: 'all',
 minChunks: 2,
 minSize: 0,
 name: 'common',
 enforce: true,
 priority: -11
 vendors: {
 test: /[\\/]node_modules[\\/]/,
 name: "vendors",
 priority: -10,
 chunks: 'all',
 reuseExistingChunk: true,
 enforce: true
 style: {
 name: 'style',
 test: /\.less$/,
 chunks: 'all',
 enforce: true
 runtimeChunk:{
 name:'manifest'
 },

monjs,mon部分也是可以的,monjs是一样的,配置minChunks最小为2就可以了),提供第三方类库。

我们看下打包效果

mon文件以及提三方文件集合verndors文件,嗯,目前解决了我们要解决的问题,上面单页面场景同样适用,浏览器缓存这个一般不会变得vendors,也达到了提升效率问题,

但是有没有想过一个问题,就是每一次webpack构建过程,是不是都要打一次这个包呢,浪费时间了吧,于是我们采用什么方式呢,没错~采用DllPlugin与DllReferencePlugin来提取一次第三方,

代码同样引用dll

 new webpack.DllReferencePlugin({
 context: __dirname,
 manifest: require('./distDll/dll/react.manifest.json')
 })

构建效果

效果就是大幅度提升构建速度。

最终配置文件

const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
 mode: 'development',
 entry: {
 app1: './app1.js',
 app2: './app2.js'
 output: {
 path: path.resolve(__dirname, './build/'),
 filename: "[name]-[chunkhash].js"
 devtool: "source-map",
 module: {
 rules: [
 test: /\.less$/,
 use: [
 MiniCssExtractPlugin.loader,
 loader: 'css-loader',
 // options: {
 // sourceMap: true,
 // modules: true,
 // localIdentName: '[name]---[local]---[hash:base64:5]'
 // }
 'less-loader',
 exclude: /node_modules/
 test: /\.js$/,
 use: [
 'cache-loader',
 loader: 'babel-loader',
 options: {
 // cacheDirectory: path.join(__dirname,'./build/', 'babel_cache')
 // happyPackMode: true,
 // transpileOnly: true
 exclude: /node_modules/
 optimization: {
 runtimeChunk: {
 "name": "manifest"
 splitChunks: {
 chunks: 'all',
 cacheGrou凡科抠图: {
 default: false,
 vendors: false,
 common: {
 test: /\.(s*)js$/,
 chunks: 'all',
 minChunks: 2,
 minSize: 0,
 name: 'common',
 enforce: true,
 priority: -11
 // vendors: {
 // test: /[\\/]node_modules[\\/]/,
 // name: "vendors",
 // priority: -10,
 // chunks: 'all',
 // reuseExistingChunk: true,
 // enforce: true
 // },
 style: {
 name: 'style',
 test: /\.less$/,
 chunks: 'all',
 enforce: true
 runtimeChunk:{
 name:'manifest'
 plugins: [
 new MiniCssExtractPlugin({
 filename: '[name].[hash:5].css',
 new CleanWebpackPlugin(),
 new HtmlWebpackPlugin({
 title: 'index1',
 ',
 ',
 chunks: ['app1', 'common'],
 // hash: true
 new HtmlWebpackPlugin({
 title: 'index2',
 ',
 ',
 chunks: ['app2', 'common'],
 // hash: true
 new webpack.HashedModuleIdsPlugin(),
 new webpack.DllReferencePlugin({
 context: __dirname,
 manifest: require('./distDll/dll/react.manifest.json')
}

mon内容请搜索凡科以前的文章或继续浏览下面的



在线客服

关闭

客户服务热线
4008-888-888


点击这里给我发消息 在线客服

点击这里给我发消息 在线客服