Webpack

1.模块封装

立即执行函数

(function(window) {
  var name = 'Xiaoming';
  var sex = 'man';
  function tell() {
    console.log('My name is ', name);
    console.log('My sex is ', sex);
  }
  window.Xiaomingmodule = { tell };
})(window)

ES6模块封装

export function sum(a, b) {
  return a+b
}

2. webpack打包

简单原理:将模块打包成立即执行函数

打包过程:

  1. 从入口文件开始,分析整个应用的依赖树
  2. 将每个依赖模块包装起来,放到一个数组中待用
  3. 实现模块加载的方法,并把它放到模块的执行环境中,确保模块间可以相互调用
  4. 把执行入口文件的逻辑放到一个函数表达式中,并立即执行这个函数

webpack自更新:webpack-dev-server

3.webpack配置文件

const path = require('path')

module.exports = {
    entry: './app.js', //指定入口文件
    output: {
        path: path.join(__dirname, 'dist'), //出口文件路径,必须是绝对路径
        filename: 'bundle.js'
    },

    // devServer自更新配置,devServer不生成实际打包文件
    devServer: {
        port: 3000, //服务端口
        publicPath: '/dist' //资源路径
    }

  // 添加loader,注意:添加前首先需要使用npm安装相应loader
    module: {
        rules: [
            {
                test: /\.css$/, //正则,应用于何种文件资源
                use: [
                    //loader配置顺序和加载顺序是相反的
                    'style-loader',  //将CSS样式文件加入页面,后执行放前面
                    'css-loader' //解析CSS,先执行,放后面
                ]
            }
        ]
    }
}

4.babel

功能:将ES6代码转化为ES5代码
.babelrc配置文件

//首先需要安装 @babel/core和@babel/cli包
{
    "presets": ["@babel/preset-env"] //需要安装 @babel/preset-env包,用来指定将ES6转换为ES5的转换规则
}

5.webpack添加babel

module.exports = {
    //声明不需要写后缀的文件类型
    resolve: {
        extensions: ['js', 'jsx', 'json']
    },

    // 添加babel loader
    module: {
        rules: [
            {
                test: /\.jsx?/, //正则,应用于js和jsx文件
                exclude: /node_modules/, //忽略node_modules内文件
                use: {
                    loader: 'babel-loader',  //使用babel-loader来转换js和jsx文件
                    //配置选项
                    options: {
                        babelrc: false, //指定不再寻找babelrc文件
                        //指定转换规则
                        presets: [
                            require.resolve('@babel/preset-react'), //转义jsx规则
                            [require.resolve('@babel/preset-env', {modules: false})] //转义ES6规则
                        ],
                        cacheDirectory: true //编译结果进行缓存
                    }
                }
            }
        ]
    },
}

6.webpack热更新

自更新与热更新区别:热更新不需要刷新页面,直接更新

// webpack配置
const webpack = require('webpack')

module.exports = {
    entry: './aindex.jsx', //指定入口文件
    //配置热更新
    devServer: {
        hot: true,
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ]
}

//入口文件配置
if(module.hot) {
    module.hot.accept(err => {
        if(err) {
            console.log('HMR error!');
        }
    })
}

7.webpack性能调优

代码压缩及加快构建

const path = require('path')
const TerserPlugin = require('terser-webpack-plugin')
const HappyPack = require('happypack')
//根据cpu数量构建线程池,利用多进程实现多线程
const happyThreadPool = HappyPack.ThreadPool({size: OscillatorNode.cpus().length})

module.exports = {
    noParse: /node_modules\/(jquery\.js)/,  //减少解析
    //专门字段用来进行压缩配置
    optimization: {
        minimizer: [
            new TerserPlugin({
                cache: true, //开启缓存,加快构建速度
                parallel: true, //开启多线程加快压缩速度
                terserOptions: {
                    compress: {
                        //删除不必要代码
                        unused: true, 
                        drop_debugger: true,
                        drop_console: true,
                        dead_code: true
                    }
                }
            })
        ]
    },

    //使用thread-loader开启多线程加快构建速度
    rules: [
        {
            test: /\.js$/,
            include: path.resolve('src'),
            use: [
                'thread-loader',  //放在最前
                'babel-loader', //继续加载其他loader
            ]
        }
    ],

    plugins: [
        new HappyPack({
            id: 'jsx',
            threads: happyThreadPool, //线程池
            loaders: ['babel-loader'] //所有loaders,注意配置的loader是否支持loader
        })
    ]
}

打包结果分析
打包结果可视化插件:webpack-bundle-analyzer

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = {
    plugins: [
        new BundleAnalyzerPlugin()
    ]
}

tree-shaking
作用:去除无用代码,当import函数并没有被使用时,打包会去掉,在mode==production时有效果。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。