Webpack 基础配置

188 阅读3分钟

一、开发环境配置

1. 初始化 package.json

npm init

2. 安装 webpack

npm install webpack webpack-cli -g
npm install webpack webpack-cli -D

3. 下载安装基本配置所用到的 loader、plugin

// 打包样式资源相关的loader
npm i style-loader css-loader less-loader less -D

// 打包html资源相关的plugin
npm i html-webpack-plugin --save-dev

// 打包图片资源
npm i html-loader url-loader file-loader --save-dev

// devserver
npm i webpack-dev-server -D

4. webpack.config.js 配置文件

const { resolve } = require('path'); 
const  HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = { 
	// 入口文件
	entry: './src/js/index.js',     
    // 打包后的资源输出目录及命名方式
    output: { 
    	filename: 'js/built.js',    
        path: resolve(__dirname, 'build') 
    },
    module: { 
    	rules: [ 
            { 
            	// 处理 less 资源 
                test: /\.less$/, 
                // style-loader: 将 js 中的样式最终以 style 标签的形式添加到 head 中
                // 将 css 文件用 commonjs 解析成 js 文件,内容是样式字符串
                use: ['style-loader', 'css-loader', 'less-loader'] 
            },
            {
            	// 处理 css 资源 
                test: /\.css$/, 
                use: ['style-loader', 'css-loader'] 
            },
            { 
            	// 处理图片资源 
                test: /\.(jpg|png|gif)$/, 
                loader: 'url-loader', 
                options: { 
                	// 小于 8kb 的图片,用 base64 编码 
                    // 减少服务器请求次数
                	limit: 8 * 1024, 
                    // 重命名:取图片hash值前十位 + 图片原扩展名
                    name: '[hash:10].[ext]', 
                    // 关闭 es6 模块化,使用 commonjs 解析
                    esModule: false, 
                    // 输出在 build/imgs 目录下
                    outputPath: 'imgs' 
                } 
            },
            { 
            	// 处理 html 中 img 资源:<img src='' alt='' />
                test: /\.html$/, 
                loader: 'html-loader' 
            },
            { 
            	// 处理其他资源 
                exclude: /\.(html|js|css|less|jpg|png|gif)/, 
                loader: 'file-loader', 
                options: {
                	name: '[hash:10].[ext]', 
                    outputPath: 'media' 
                 } 
             } 
         ] 
     },
     plugins: [ 
     	// 在 build 目录下生成空的 html,自动引入打包输出的所有资源(JS/CSS)
        new HtmlWebpackPlugin({ 
        	template: './src/index.html' 
        }) 
     ],
     mode: 'development', 
     devServer: { 
     	// 项目构建后路径
     	contentBase: resolve(__dirname, 'build'), 
        // 启动 gzip 压缩
        compress: true, 
        port: 3000, 
        // 开启 HMR 功能
        hot: true, 
        // 打包编译完成自动打开浏览器
        open: true 
     },
 };

二、生产环境配置

1. 下载安装所需要的包

// 提取 css 成单独文件
npm i mini-css-extract-plugin --save-dev

// css 兼容性处理
npm i postcss-loader postcss-preset-env --save-dev

// 压缩 css
npm i optimize-css-assets-webpack-plugin --save-dev

// js 语法检查
npm i eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import --save-dev

// js 兼容性处理
npm i babel-loader @babel/core @babel/preset-env @babel/polyfill core-js --save-dev

2. 生产环境配置

webpack.config.js
const { resolve } = require('path'); 
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin' );
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 定义 nodejs 环境变量:决定使用 browserslist 的哪个环境 
process.env.NODE_ENV = 'production';

// 复用 loader 
const commonCssLoader = [ 
	// 取代 style-loader  作用:提取 js 中的 css 成单独文件
	MiniCssExtractPlugin.loader, 
    'css-loader', 
    { 
    	// 需要在 package.json 中定义 browserslist 
        loader: 'postcss-loader', 
        options: { 
        	ident: 'postcss', 
            plugins: () => [require('postcss-preset-env')()] 
         } 
     } 
];

module.exports = { 
	entry: './src/js/index.js', 
    output: { 
    	filename: 'js/built.js', 
        path: resolve(__dirname, 'build') 
    },
    module: { 
    	rules: [ 
        	// 当文件要被多个 loader 处理,需要指定 loader 执行的先后顺序
            // 对于js文件的处理先执行 eslint 语法检查, 后执行 babel 兼容处理
            { 
            	// 在 package.json 中 eslintConfig --> airbnb 
                test: /\.js$/, 
                exclude: /node_modules/, 
                // 优先执行 
                enforce: 'pre', 
                loader: 'eslint-loader', 
                options: { 
                	// 自动修复 eslint 的错误
                	fix: true 
                } 
            },
            { 
            	// 以下 loader 只会匹配一个 
                // 注意:不能有两个配置处理同一种类型文件 
                oneOf: [
                  { 
                      test: /\.css$/,
                      use: [...commonCssLoader] 
                  },
                  { 
                      test: /\.less$/, 
                      use: [...commonCssLoader, 'less-loader'] 
                  },
                  { 
                      test: /\.js$/, 
                      exclude: /node_modules/, 
                      loader: 'babel-loader', 
                      options: { 
                          // 预设:指示 babel 做怎么样的兼容性处理
                          presets: [ 
                              [ 
                                  '@babel/preset-env', 
                                  { 
                                      // 按需加载
                                      useBuiltIns: 'usage', 
                                      // 指定 core-js 版本
                                      corejs: {
                                          version: 3
                                      }, 
                                      // 指定兼容性做到哪个版本浏览器
                                      targets: { 
                                          chrome: '60', 
                                          firefox: '50' 
                                      } 
                                  } 
                              ] 、
                          ],
                          // 开启 babel 缓存 
                          // 第二次构建时,会读取之前的缓存 
                          cacheDirectory: true
                      } 
                  },
                  { 
                      test: /\.(jpg|png|gif)/, 
                      loader: 'url-loader', 
                      options: { 
                          limit: 8 * 1024, 
                          name: '[hash:10].[ext]', 
                          outputPath: 'imgs', 
                          esModule: false 
                      }
                  },
                  { 
                      test: /\.html$/, 
                      loader: 'html-loader' 
                  },
                  { 
                      exclude: /\.(js|css|less|html|jpg|png|gif)/, 
                      loader: 'file-loader', 
                      options: { 
                          outputPath: 'media' 
                      } 
                  } 
        	   ] 
            } 
        ] 
    },
    plugins: [ 
    	new MiniCssExtractPlugin({ 
        	// 重命名输出的 css 文件
        	filename: 'css/built.css' 
        }), 
        // 压缩 css
        new OptimizeCssAssetsWebpackPlugin(), 
        new HtmlWebpackPlugin({ 
        	template: './src/index.html', 
            // 压缩 html 代码
            minify: { 
            	// 移除空格
            	collapseWhitespace: true, 
                // 移除注释
                removeComments: true 
            } 
        }) 
    ],
    // 生产环境下会自动压缩 js 代码
    mode: 'production',
    // source-map 模式
    devtool: 'eval-source-map',
    resolve: { 
    	alias: { 
        	@: resolve(__dirname, 'src/css') 
        },
        extensions: ['.js', '.json', '.jsx', '.css'], 
        modules: [resolve(__dirname, '../../node_modules'), 'node_modules'] 
     },
};
package.json
// 对于 css 兼容性处理
"browserslist": { 
	"development": [ 
    	"last 1 chrome version", 
        "last 1 firefox version", 
        "last 1 safari version" 
     ],
    "production": [ 
    	">0.2%", 
        "not dead", 
        "not op_mini all" 
     ] 
 }
// 配置 eslint 语法检查
"eslintConfig": { 
 	"extends": "airbnb-base", 
    "env": { "browser": true } 
 }