webpack学习笔记

作者: 説好的妹紙呢 | 来源:发表于2019-05-29 18:26 被阅读0次

    全局安装webpack

        npm install webpack webpack-cli -g
    

    全局安装webpack会有个问题,就是当你有两个项目依赖于不同版本的webpack,就会有一个项目打包不了,所以还是不全局安装webpack比较好。

    在当前项目安装webpack

    1. 新建webpack-demo目录,然后进行npm项目初始化
    npm init 或者 npm init -y
    
    1. 在刚创建出来的package.json中添加private字段
    "private": true    /**表示私有的**/
    
    1. 如果webpack已经全局安装,需要卸载
    npm uninstall webpack webpack-cli -g  /**卸载全局安装的webpack**/
    
    1. 在项目根目录下执行安装命令
    npm install webpack webpack-cli --save-dev
    
    1. 使用npx打印出当前的webpack版本
    npx webpack -v
    

    安装指定版本的webpack

    npm info webpack /*查看webpack所有版本信息*/
    npm install webpace@4.29.6 --save-dev
    

    webpack的配置文件

    在项目根目录新建文件webpack.config.js

    const path = require('path');
    
    module.exports = {
        entry: './index.js',
        output: {
            filename: 'bundle.js',
            path: path.resolve(__dirname, 'dist')
        }
    }
    

    webpack手动打包命令

    npx webpack /**默认会使用根目录下的webpack.config.js配置文件进行打包**/
    npx webpack --config webpack.config.js /**指定配置文件打包**/
    

    使用npm scripts 简化webpack命令

    1. 在package.json中的scripts字段下添加bundle字段
    "bundle": "webpack"
    
    1. 使用npm命令打包
    npm run bundle
    

    使用file-loader打包图片

    1. 安装file-loader
    npm install file-loader --save-dev
    
    1. 在配置文件webpack.config.js中添加字段
    module: {
        rules: [
            {
                test: /\.(jpg|png|svg|gif)$/,
                use: {           
                    loader: 'file-loader',
                    options: {
                       name: '[name].[ext]', /**原名字输出**/
                       outputPath: 'images/', /**打包后存放图片的文件夹**/
                    }
                }
            }
        ]
    }
    

    使用url-loader打包图片

    1. 安装url-loader
    npm install url-loader --save-dev
    
    1. 在配置文件webpack.config.js中添加字段
    module: {
        rules: [
            {
                test: /\.(jpg|png|svg|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'images/',  
                        limit: 204800, /**小于20kb的图片,打包成base64放到bundle.js文件**/
                    }
                }
            }
        ]
    }
    

    使用style-loader和css-loader打包css文件

    1. 安装style-loader 和 css-loader
    npm install style-loader css-loader --save-dev
    
    1. 在webpack.config.js文件中添加配置
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    }
    

    使用sass-loader打包.sass文件

    1. 安装sass-loader 和 node-sass
    npm install sass-loader node-sass --save-dev
    
    1. 在webpack.config.js文件中添加配置
    module: {
        rules: [{
            test: /\.sass$/,
            use: ['style-loader', 'css-loader', 'sass-loader']
        }]
    }
    

    数组形式的loader是从下到上,从右到左执行 sass-loader -> css-loader -> style-loader

    使用postcss-loader自动添加css厂商前缀

    1. 安装postcss-loader
    npm install postcss-loader --save-dev
    
    1. postcss-loader需要配合autoprefixer插件使用
    npm install autoprefixer --save-dev
    
    1. 在项目根目录添加postcss.config.js文件
    module.exports = {
        plugins: [
            require('autoprefixer');
        ]
    }
    
    1. 在webpack.config.js中添加配置
    module: {
        rules: [{
            test: /\.scss$/,
            use: ['style-loader', 'css-loader', 'sass-loader', 'postcss-loader']
        }]
    }
    
    1. 确保所有的scss文件都会被所有loader处理,修改webpack.config.js中的配置
    {
        test: /\.scss$/,
        use: [
                'style-loader',
                {
                    loader: 'css-loader',
                    options: {
                        /**确保每个scss都被所有loader处理**/
                        importLoaders: 2,
                        /**分模块打包css**/
                        modules: true
                    }
                 },
                 'sass-loader',
                 'postcss-loader'
         ]
    }
    

    使用file-loader打包字体文件

    1. 安装file-loader
    npm install file-loader --save-dev
    
    1. 在webpack.config.js文件中添加modules
    {
        test: /\.(eot|ttf|svg)$/,
        use: {
            loader: 'file-loader'
        }
    }
    

    使用插件使webpack打包更便捷

    1). 安装自动生成index.html插件 html-webpack-plugin

    1. 安装html-webpack-plugin
    npm install html-webpack-plugin --save-dev
    
    

    htmlWebpackPlugin 会在打包结束后,自动生成index.html文件,并把对应的js引入index.htm文件中

    1. 在webpack.config.js中引入插件
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    plugins: [
        new HtmlWebpackPlugin({
            template: 'src/index.html' /**自动以src/index.html为模板,在dist目录下生成新的index.html文件**/
        })
    ]
    
    

    2)使用clean-webpacl-plugin插件自动删除dist插件再打包

    1. 安装插件clean-webpack-plugin
    npm install clean-webpack-plugin --save-dev
    
    1. 在webpack.config.js中使用插件
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    plugins: [new CleanWebpackPlugin({})] /**默认清除的是dist目录**/
    

    sourceMap配置

    sourceMap 映射src目录的源文件,能定位到哪行报错

    1. 开启sourceMap,在wepback.config.js中添加配置
    devtool: 'source-map'
    
    1. sourceMap的最佳实现
    devtool: 'cheap-module-eval-source-map' /**开发环境中使用**/
    
    devtool: 'cheap-module-source-map' /**生产环境**/
    

    使用WebpackDevServer提高开发效率

    1. 安装webpack-dev-server
    npm install webpack-dev-server --save-dev
    
    1. 在webpack.config.js中配置devServer
    devServer: {
        contentBase: './dist',
        open: true,     /**open true 可以自动打开浏览器**/
        proxy: {
         "/api": "http://new.junbang.com/" /**请求api代理转发**/ 
        },
        port: 8081,  /**端口号**/ 
    }
    
    1. 在package.json中添加watch命令
    "scripts": {
        "watch": "webpack --watch",
        "start": "webpack-dev-server"
    }
    

    使用:npm run watch 监听文件有变化自动打包
    使用:npm run start 可以自动监听,自动打包, 自动刷新浏览器

    自定义server

    1. 需要安装express和webpack-dev-middleward这两个插件
    npm install express webpack-dev-middleware --save-dev
    
    1. 新建server.js 并引入插件
    const express = require('express');
    const webpack = require('webpack');
    const webpackDevMiddleware = require('webpack-dev-middleware');
    const config = require('./webpack.config.js');
    const complier = webpack(config);
    
    const app = express();
    
    app.use(webpackDevMiddleware(complier, {
        publicPath: config.output.publicPath
    }));
    
    app.listen(3000,() => {
        console.log('server is running on prot 3000');
    });
    
    1. 在package.json中设置serve命令
    "scripts": {
        "serve": "node server.js"
    }
    

    npm run serve 使用的就是我们server.js配置的服务器
    不过server.js还需要写很多,这只是简单的server

    模块热更新HMR

    1. 开启模块热更新,在webpack.config.js中添加配置
    devServer: {
        hot: true,
        hotOnly: true,  /**hotOnly: false 浏览器可以自动刷新**/
    }
    
    1. 使用HMR插件,在webpack.config.js中引入插件
    const webpack = require('webpack');
    plugins: {
        new webpack.HotModuleReplacementPlugin()
    }
    

    使用npm run start重启服务使新的配置生效

    模块热更新HMR作用:

    css编写. 修改无需重新刷新浏览器就可显示效果
    js模块发生改变可以指定更新当前js模块,不需要刷新浏览器

    1. js模块热更新,在index.js文件中编写代码
    import number from './number';
    number();
    
    if (module.hot) {
        module.hot.accept('./number', () => {
        /**当number模块有改变重新渲染**/
         number();
        }
    }
    

    使用Babel处理ES6语法

    1. 安装babel-loader 和 @babel/core
    npm install --save-dev babel-loader @babel/core
    
    1. 在webpack.config.js中添加配置
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader",
            options: {
                presets: ["@babel/preset-env"]
            }
        }]
    }
    
    1. 安装@babel/preset-env模块对ES6语法进行翻译
    npm install @babel/preset-env --save-dev
    
    1. 在webpack.config.js中的modules rules babel-loader 中配置options对象
    options: {
        presets: ["@babel/preset-env"]
    }
    /**或者在项目根目录下创建配置文件.bablerc**/
    {
        "presets": ["@babel/preset-env"]
    }
    
    1. 使用@babel/polyfill 加上低版本没有的语法, 比如map() . Promise等
    npm install --save @babel/polyfill
    
    1. 在所以代码运行之前,可以放在入口文件index.js最顶部
    import "@babel/polyfill";
    
    1. polyfill默认会把所有翻译过代码都加进来,有时候我们没有用到的新方法,也有了翻译的方法在里面了,所以我们要过滤掉,没用上的就不要加载进来了,这样包更小,所以在webpack.config.js babel-loader中修改配置
    options: [['@babel/preset-env', {
        useBuiltIns: 'usage'
    }]]
    
    1. 已经支持ES6语法的浏览器版本,没必要在翻译所以我们可以指定浏览器版本
    options: [['@babel/preset-env', {
        targets: {
            chrome: "67" /**更多浏览器版本配置去babel官网查看**/
        },
        useBuiltIns: 'usage'
    }]]
    
    1. 当指定了useBuiltIns: 'usage',会自动引入@babel/polyfill,所以可以去掉index.js import的@babel/polyfill,但是可以需要安装依赖
    npm install --save core-js
    
    1. 如果是写业务代码以上配置没问题,如果要写框架. 类库. 第三方模块什么的,为了避免变量的全局污染(因为polyfille翻译的变量挂载到全局变量)而使用plugin-transform-runtime插件

    2. 安装transform-runtime插件

    npm install --save-dev @babel/plugin-transform-runtime
    npm install --save #babel/runtime
    
    1. 在webpack.config.js中修改配置
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
                plugins: [["@babel/plugin-transform-runtime", {
                    corejs: 2
                    helpers: true,
                    regenerator: true
                    useESModules: false
                }]]
            }
        }]
    }
    
    1. 因为我们配置了corejs: 2,所以要加装corejs的依赖
    npm install --save @babel/runtime-corejs2
    

    配置React代码的打包

    babel也可以打包react代码

    1. 安装react框架
    npm install react react-dom --save
    
    1. 安装@babel/preset-react
    npm install --save-dev @babel/preset-react
    
    1. 在.babelrc中添加配置
    presets: ["@babel/preset-env","@babel/preset-react"]
    

    使用Tree Shaking去掉没有引用的方法/ 模块

    Tree Shaking只支持 ES Module 就是import export不支持require('')

    1. 在mode: 'development'中配置Tree Shaking, 在webpack.config.js中
    optimization: {
        usedExports: true
    }
    
    1. 在mode: 'production'中 默认就有,不需要添加任何配置

    2. 在package.json中配置不需要Tree Shaking的模块

    "sideEffects": false   /**所有模块都需要Tree Shaking**/
    "sideEffects": ['@babel/polly-fill', '*.css']  /**对这两个模块不做Tree Shaking**/
    

    Development 和 Production 模式的区分打包

    1. 创建webpack.common.js 放公有的配置项

    2. 创建webpack.dev.js 放开发独有的配置项

    3. 创建webpack.prod.js 放生产独有的配置项

    4. 使用webpack-merge 把webpack.common.js合并到其他两个文件

    npm install webpack-merge --save-dev
    
    1. 在webpack.dev.js中引入插件
    const merge = require('webpack-merge');
    const commonConfig = require('./webpack.common.js');
    
    const devConfig = {
    ...
    }
    module.exports = merge(commonConfig, devConfig);
    

    在webpack.prod.js中也作跟webpack.dev.js同样的处理

    Code Splitting 代码分割

    1. 同步加载模块 在webpack.config.js中配置splitChunks
    optimization: {
       splitChunks: {
           chunks: 'all'
       }
    }
    
    1. 异步加载模块无需任何配置默认就会自动分割

    2. 创建一个异步加载的js模块

    /** webpackChunkName: "lodash" 给这个模块起这个文件名 **/
    function getComponent() {
        return import(/* webpackChunkName: "lodash"*/ 'lodash').then(({default: _}) => {
            var element = document.createElement('div');
            element.innerHtml = _.join(['@', 'bang']);
            return element
        });
    }
    getComponent().then(element => {
        document.body.appendChild(element);
    });
    
    1. 安装babel-plugin-dynamic-import-webpack对异步加载模块语法进行翻译
    npm install @babel/plugin-syntax-dynamic-import  --save-dev
    
    1. 在.babelrc配置文件中使用plugin-syntax-dynamic-import插件
    plugins: ["@babel/plugin-syntax-dynamic-import"]
    

    SplitChunksPlugin配置参数详解

    /** 在webpack.config.js文件中 **/
    optimization: {
        splitChunks: {
            /** all:-- 所有模块都分割 **/
            /** async -- 只对异步加载的模块进行分割 **/
            /** initial -- 只对同步模块进行分割 **/
            chunks: 'all', 
            minSize: 30000,  /** 大于30000b(30kb)才会分割 **/
            maxSize: 0,  /**  一般不配置,会对大文件再次分割 **/
            minChunks: 1,  /**  引用这个模块超过一次就会分割 **/
            maxAsyncRequests: 5, /**  同时只能加载分割5个库 **/
            maxInitialRequests: 3, /**  最多分割出3个文件 **/
            automaticNameDelimiter: "~", /** 文件名连接符  **/
            name: true
            cacheGroups: {
                /** 同步模块加载必需配置
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    /** 如果模块同时满足cacheGroups和default, **/
                    /** 根据priority来决定模块的归属谁的值大属于谁 **/
                    priority: -10, 
                    filename: 'vendors.js' /** 打包成的文件名 **/
                },
            /** 同步非node_modules里面的模块配置专用 **/
                default: {
                    priority: -10,
                    /** 已经打包过的模块忽略 **/
                    /** 不再打包分割 **/
                    reuseExistingChunk: true,
                    filename: 'common.js'
                }
            }
        }
    }
    

    lazy loading 懒加载异步模块

    1. 打包分析工具

    首先在打包的时候生成josn格式的描述文件,然后在package.json中添加命令

    scripts: {
        "dev-build": "webpack --profile --json > stats.json --config webpack.dev.js"
    
    }
    

    使用:npm run dev-build
    生成的.stats.json文件可以用来分析

    使用Preloading, 空闲时候,静默加载我们的异步模块

    1. 查看js文件中代码的使用率,打开控制台 command + shift + p
    2. 搜索 Coverage 选中show Coverage 然后点击录制按钮变红后刷新页面
    3. 在index.js中创建一个异步加载模块js的方法
    document.addEventListener('click', () => {
        import(/* webpackPrefetch: true */ './click.js').then(({default: func}) => {
         func();
        });
    });
    

    正常情况下呢,我们只有在点击的时候,才加载click.js,但是配置了Prefetch: true,就会空闲时主动加载我们的click.js。空闲时主动加载解决了异步加载慢的问题,因为文件加载过了,再点击加载就会使用缓存的文件。

    css文件代码分割

    1. webpack 用style-loader处理的css会放到文件<head>标签中
    2. 使用mini-css-extract-plugin把css分割成单独文件
    npm install --save-dev mini-css-extract-plugin
    
    1. 这个插件不支持热更新(截止目前),所以一般是生产环境才用
    2. 在webpack.prod.js中 将style-loader替换为MiniCssExtractPlugin.loader
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    plugins: [
        new MiniCssExtractPlugin({});
    ]
    module: {
        rules: [
           {
               test: /\.css$/,
               use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader' ]
        ]
    }
    
    1. 过滤Tree Shakking, 在package.json中添加配置
    "sideEffects": ["*.css"]
    
    1. 配置filename和chunkFilename, 在webpack.prod.js中
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: '[name].chunk.css'
        });
    }
    
    1. 使用optimize-css-assets-webpack-plugin对css合并和压缩
    npm install --save-dev optimize-css-assets-webpack-plugin
    
    1. 在webpack.prod.js中使用optimize-css-assets-webpack-plugin
    const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    optimization: {
        minimizer: [new OptimizeCssAssetsPlugin({})]
    }
    

    多个入口文件引用的css打包到一个css文件

    1. 借助splitChunks, 在webpack.prod.js中添加配置
    optimization: {
        splitChunks: {
            cacheGroups: {
                styles: {
                    name: 'styles',
                    test: /\.css$/,
                    chunks: 'all',
                    enforce: true
                }
            }
        }
    }
    
    1. 还可以把一个入口文件引入的所有css打包到对应的一个文件。这样每个入口引用的css,就会生成对应一个css文件。这个配置也借助splitChunks,在webpack.prod.js中配置
    optimization: {
        splitChunks: {
            cacheGroups: {
                mainStyles: {
                    name: 'main',
                    test: (m,c,entry = 'main') => m.constructor.name === 'CssModule && recursiveIssuer(m) === entry,
                    chunks: 'all',
                    enforce: true
                }
            }
        }
    }
    

    webpack与浏览器缓存

    1. 在webpack.prod.js中配置contenthash
    output: {
       filename: '[name].[contenthash].js',
       chunkFilename: '[name].[contenthash].js'
    }
    

    contenthash在文件没有改变时,它不会变,对应的文件有改变它的值就会变,这样浏览器加载的就是新文件

    通过webpack.ProvidePlugin插件自动帮我们引用没有import的模块

    1. 在webpack.common.js中配置ProvidePlugin
    const webpack = request('webpack');
    plugins: [
        new webpack.ProvidePlugin({
        $: 'jquery'
        })
    ]
    

    解决问题: 有的模块使用的是jquery,但是没有import jquery,$对象找不到,只在首页引入jquery是不行的,这时候借助webpack.ProvidePlugin,帮我们在使用$对象的模块引入jquery。

    让this都指向window

    1. 安装
      imports-loader
      npm install imports-loader --save-dev
    
    1. 在webpack.common.js中添加配置
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            use: [{
                loader: 'babel-loader',
            }, {
                loader: 'imports-loader?this=>window'
            }]
        }]
    }
    

    环境变量的使用

    1. 在webpack.common.js中使用Env
    comst merge = require('webpack-merge');
    const prodConfig = require('./webpack.prod.js);
    const devConfig = require('./webpack.dev.js');
    module.exports = (env) => {
     if (env && env.production) {
        return merge(commonConfig, prodConfig);
     } else {
        return merge(commonConfig, devConfig);
     }
    }
    
    1. 在package.json中修改命令
    "scripts": {
        "dev-build": "webpack -- config ./webpack.common.js",
        "build": "webpack --env.production  --config ./webpack.common.js"
    }
    

    Library的打包

    1. 创建一个自己的包模块library
    npm init -y
    
    1. 在包目录下新文件src/math.js 和 src/string.js
    2. 在src/math.js中编写代码
    export function add(a, b) {
        return a + b;
    }
    export function minus(a, b) {
        return a - b;
    }
    export function multiply(a, b) {
        return a * b;
    }
    export function division(a, b) {
        return a / b;
    }
    
    1. 在src/string.js中编写代码
    export function join(a, b) {
     return a + " " + b;
    }
    
    1. 在src/index.js中编写代码
    import * as math from './math.js';
    import * as string from './string';
    
    export default { math, string }
    
    1. 在项目中安装webpack 和 webpack-cli
    npm install webpack webpack-cli --save
    
    1. 在项目中创建webpack.config.js
    const path = require('path');
    module.exports =  {
        mode: 'production',
        entry: './src/index.js'
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'library.js',
            library: 'library',
            libraryTarget: 'umd'
        }
    }
    
    1. 在package.js中配置入口文件和打包命令
    main: './src/index.js',
    scripts: {
        "build": "webpack"
    }
    
    1. 别人使用我们的库可能用到的引入方式
      1、 import library from 'library';
      2、const library = require('library');
      3、 require(['library'], function() {});
      4、 <script src="./library.js"></script>

    2. 通过在webpack.config.js中配置libraryTarget: 'umd'可以使用前面三种引用

    3. 通过在webpack.config.js中配置library: 'library'可以使用<script>引用

    4. 在自己的库中使用别人的库,这里引入lodash库

    npm install lodash --save
    
    1. 在src/string.js中 使用lodash
    import _ from 'lodash';
    
    export function join(a, b) {
        return _.join([a, b], ' ');
    }
    
    1. 问题:默认的lodash也会被打包到我们的代码中,而别人不知道,也有可能在自己项目中,引入了自己的lodash,造成模块冗余,所以需要在webpack.config.
    externals: ['lodash']
    

    注意:这个时候别人用我们的库需要手动引入lodash再引入library(我们的库)

    1. 让别人方便的使用我们的代码,可以在package.json中配置
    "main": "./dist/library.js",
    
    1. 在npm官网注册一个账号,并把我们的库上传到npm
    npm adduser -- 回车添加账号和密码
    npm publish -- 把包上传到npm仓库
    
    1. 安装我们的库
    npm install library
    
    1. 我们自己创建的库名跟npm上的库名不能相同,不然有可能上传不了。

    PWA的打包配置

    PWA作用是缓存页面,当服务器挂掉了,还是可以看到原来缓存的页面

    1. 安装workbox-webpack-plugin插件
    npm install workbox-webpack-plugin --save-dev
    
    1. 在webpack.prod.js中使用workbox-webpack-plugin插件
    const WorkboxPlugin = require('workbox-webpack-plugin');
    plugins: [
        new WorkboxPlugin.GenerateSW({
            clientsClaim: true,
            skipWaiting: true
        })
    ]
    
    1. 在index.js中看看浏览器是否支持PWA,并注册我们要缓存的文件
    if('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
            navigator.serviceWorker.register('/service-worker.js)
                .then(registration => {
                     console.log('service-worker registed');
                }).catch(error => {
                     console.log('service-worker register error');
                });
        }
    }
    

    这样注册了service-worker.js之后,本来我们需要npm run dev 把服务开启之后能访问,如果关掉服务再刷新,因为已经访问成功过一次,有了缓存,所以还是可以看到页面

    webpack打包TypeScript

    1. 安装ts-loader 和 typescript
    npm install ts-loader typescript --save-dev
    
    1. 在webpack.config.js中添加配置
    const path = require('path');
     module.exports = {
       entry: './srcindex.tsx',
       module: {
          rules: [{
            test: /\.[tsx]|[ts]?$/,
            use: 'ts-loader',
            exclude: /node_modules/
          }]
       },
       output: {
          filename: 'bundle.js',
          path: path.resolve(__dirname, 'dist')
       }
    }
    
    1. 在项目根目录创建tsconfig.json(必需)
    {
      "compilerOptions": {
        "outDir": "./dist",
        "module": "es6",
        "target": "es5",
        "allowJs": true,
      }
    }
    

    注意:TypeScript 不能对引用的外部模块校验,比如调用lodash中的join()方法,不传参数也不报错。如需要提示,需安装@types/lodash,这样不传参数也会有提示哦。 更多库的@type检测请上网搜索!

    1. 安装@types/lodash
    npm install @types/lodash --save-dev
    

    webpackDevServer实现请求转发

    1. 在webpack.config.js中配置proxy
    devServer: {
        proxy: {
           '/api': 'http://new.junbang.vip'
        }
    }
    
    1. 更复杂的配置 比如把请求header.json 变成demo.json
    devServer: {
        proxy: {
            '/api': {
                 treget: 'http://new.junbang.vip',
                 pathRewrite: {
                     'header.json': 'demo.json'
                 }
             }
        }
    }
    
    1. 如果后台对origin做了限制可以加配置
    changeOrigin: true /**建议始终都加**/
    

    WebpackDevServer解决单页面应用路由问题

    1. 在webpack.config.js中
    devServver: {
        historyApiFallback: {
            rewrites: [{
                from: /\.*/,
                to: 'index.html'
            }]
        }
    }
    

    上面的配置等价于historyApiFallback: true,这个配置只在开发有用,上线需要对线上服务器也配置。配置好了,访问不了的页面就会显示首页

    Eslint 在wepback中的配置

    1. Eslint是什么?Eslint是约束代码的规范
    2. 安装Eslint
    npm install eslint --save-dev
    
    1. 生成配置文件
    npx eslint --init
    

    在根目录发现文件.eslintrc.

    1. 使用babel-eslint
    npm install babel-eslint --save-dev
    
    1. 在.eslintrc.js中配置
    "parser": "babel-eslint"
    
    1. 使用命令校验src目录下的js
    npx eslint src
    
    1. 忽略规则,在.eslintrc.js中
    "rules": {
      "react/jsx-filename-extension": 0
    }
    

    把规则置成0就可以忽略 1是警告 2是报错

    在webpack使用eslint-loader校验代码

    1. 安装eslint-loader
    npm install eslint-loader --save-dev
    
    1. 在webpack.config.js中添加配置
    module: {
      rules: [{
        test: /\.js$/,
        exclude: /node_modules/,
        use: ['babel-loader', 'eslint-loader']
      }]
    }
    
    1. 想要在npm run serve的时候把eslint校验的错误在浏览器上输出, 可以在webpack.config.js中配置
    devServer: {
        overlay: true
    }
    

    注意:在webpack中使用eslint-loader检测代码会影响打包速度。可以在git 生命钩子,提交代码前校验代码,不符合不给提交

    webpack性能优化

    1.提升webpack打包速度

    1)跟上技术的迭代,使用最新版node/npm/yarn/webpack

    2)尽量少用loader,loader也应该检测尽量少的代码

    3)比如校验js文件的时候,忽略/node_modules/

    4)或者只对src下面的文件校验
    include: path.resolve(__dirname, './src')
    5)合理使用插件,使用性能好的,官方推荐的

    2.合理配置resolve参数

    test: /\.jsx?$/ '?' 表示'x'可有可无 => js/jsx
    然后在webpack.config.js中添加配置

    resolve: {
     extensions: ['.js', '.jsx']
    }
    

    表示我们加载import 的时候,不写文件后缀名,默认会找.js/.jsx

    3.当我们import 一个文件夹,可能指定要找的文件名

    resolve: {
    mainFiles: ['index', 'main']
    }
    

    4.使用第三方模块时候,因为我们不会去改动这些模块,但是每次打包都会重新分析一次这些第三方模块,浪费时间,所以希望只在第一次分析,后面直接用就行。所以

    1)新建webpack.dll.js文件

    const path = require('path');
    module.exports = {
      mode: 'production',
      entry: {
      vendors: ['react', 'react-dom', 'lodash']
     },
     output: {
       filename: '[name].dll.js',
       path: path.resolve(__dirname, '../dll'),
       library: ['name'] /** library 可以把当前模块暴露出去 **/
      }
     }
    
    1. 把这些第三方模块引入index.html中,可以手动引入,也可以用插件
    npm install add-assets-html-webpack-plugin --save-dev
    
    1. 在webpack.config.js中使用插件
    const AddAssetHtmlWebpackPlugin require('add-asset-html-webpack-plugin');
    
    new AddAssetHtmlWebpackPlugin({
      filepath: path.resolve(__dirname, '../dll/vendors.dll.js')
    })
    
    1. 在写代码使用到第三方模块时,使用vendors.dll.js
    npm install dll-plugin --save-dev
    
    1. 在webpack.config.js中配置
    const webpack = require('webpack');
    plugins: [
     new webpack.DllPlugn({
       name: '[name]',
       path: path.resolve(__dirname, '../dll/[name].manifest.json')
     }),
     new webpack.DllReferencePlugin({
       manifest: path.resolve(__dirname, '../dll/vendors.manifest.json')
     })
    ]
    

    配置完成,第三方模块我们只需要手动打包一次,后面在打包项目的时候,就只会打包我们改动代码的目录src

    多页面打包配置

    1. 首先需要配置多个入口,生成多个js文件
    entry: {
      main: './src/index.js',
      list: './src/list.js'
    }
    
    1. 其次多new 几个HtmlWebpackPlugin,生成那就的html文件
    new HtmlWebpackPlugin({
      template: 'src/index.html',
      filename: 'index.html',
      chunks: ['runtime', 'vendors', 'main']
    }),
    new HtmlWebpackPlugin({
      template: 'src/index.html'
      filename: 'list.html',
      chunks: ['runtime', 'vendors', 'list']
    })
    
    1. 可能遍历configs.entry自动生成

    相关文章

      网友评论

        本文标题:webpack学习笔记

        本文链接:https://www.haomeiwen.com/subject/incutctx.html