webpack学习笔记

全局安装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自动生成
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成...
    EarthChen阅读 389评论 0 1
  • 学习目的 学习前端构建化工具 webpack,能熟练掌握 并使用 webpack 对项目进行打包优化。 ...
    _1633_阅读 1,347评论 0 7
  • http://blog.csdn.net/weizengxun/article/details/53448885 ...
    晓卢轩阅读 600评论 0 0
  • 本文主要分为:环境配置使用配置文件CSS 处理ES6 代码编辑文件压缩SASS 处理CSS 与 JS 分离文件处理...
    _月光临海阅读 489评论 0 1
  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 webpack介绍和使用 一、webpack介绍 1、由来 ...
    it筱竹阅读 11,025评论 0 21