webpack4基本配置

// webpack内部有一个事件流,tapable 1.0
let path = require('path');
let $ = require('jquery');
let webpack = require('webpack')
// 压缩js代码
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
// 生成html模版
var HtmlWebpackPlugin = require('html-webpack-plugin');
// 提取css文件
const ExtractTextPlugin = require("extract-text-webpack-plugin");

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
let pages = ['index', 'copy', 'main']
// const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
let cssExtract = new ExtractTextPlugin('css/[name].css')
let lessExtract = new ExtractTextPlugin('css/[name].less')
let sassExtract = new ExtractTextPlugin('css/[name].scss')
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin')
module.exports = {
    // entry 可以放一个字符串,可以放数组
    // 放一个对象: 多入口, 先找到每个入口,然后从各个入口分别出发,找到依赖的模块(module)
    // 然后生成一个chunk(代码块),最后把chunk写到文件系统中(Assets)
    entry: { // 入口, 多入口
        index: './src/index.js',
        copy: './src/copy.js',
        main: './src/main.js'
    }
        // 可以注入公共代码,第三方依赖
    vendor: ['jquery'] ,
    output: {
        path: path.join(__dirname, 'dist'), // 输出的文件夹,只能是绝对路径
        filename: '[name].[hash:8].js' // name是entry名字main, hash是根据文件内容生成的
    }, 
    resolve: {
        // 引入模块不加扩展名,按顺序查找
        extensions: ['.js', '.json'],
        alias: {
            // 配置别名
             '@':  '/src'
        }
    },
    // 监控源文件的变化,重新打包
     watch: true,
     watchOptions: {
         ignored: /node_modules/,
        poll: 1000, // 每秒问1000次
        aggregateTimeout: 500 //节流,不会立即开始编译
    },
    // 上线不要放上去,不安全,devtool有如下四种形式
    devtool: 'source-map', // 单独文件,可以定位到那一列出错
    // devtool: 'cheap-module-source-map', // 单独文件,体积更小,但是只能定位到那一行出错
    // devtool: 'eval-source-map', // 不会生成单独文件
    // devtool: 'cheap-module-eval-source-map', // 不会生成单独文件,体积更小,但是只能定位到那一行出错
    module: {
        rules: [
            // loader有三种写法
            // 1.use
            // 2.loader
            // 3.use + loader
             // 用babel解析语法, yarn add babel-loader @babel-core babel-preset-env babel-preset-stage-0 babel-preset-react -D
            {
                test: /\.js/,
                use: {
                    loader: 'babel-loader',
                    query: {
                        // 指定预设
                        "presets": ["react", "env", 'stage-0']
                        // modules: false 不要把es6module语法解析成es5的语法,用于shaking
                        //  "presets": ["react", "env", {modules: false}] // 分别是es6,es7,react
                    }
                }
            },
          // 把页面中的css单独提出来打包, 用插件和loader,就不用下面的style-loader了
        //   extract-text-webpack-plugin 由于extract-text-webpack-plugin目前还没有webpack4版本。可以使用该方式npm install extract-text-webpack-plugin@next
            {
                test: /\.css$/, // 转换文件的匹配正则
                // css-loader用来解析处理css文件中的url路径, 把css文件变成一个模块
                // style-loader 可以把css文件变成style标签插入head中
                // 多个loader是顺序要求的,从右往左写,因为转换的时候是从右往左转换
                use: cssExtract.extract({
                    fallback: "style-loader",
                    use: ["css-loader", 'postcss-loader'] // 自动添加前缀用postcss-loader autoprefixer 
                })
            }, 
            {
                test: /\.less$/, // 转换文件的匹配正则
                use: lessExtract.extract(["css-loader", 'less-loader']
                )
            }, {
                test: /\.scss$/, // 转换文件的匹配正则
                use: sassExtract.extract(["css-loader", 'sass-loader']
                )
            },
            { // 得到模块的绝对路径, 注入全局变量
                test: require.resolve('jquery'),
                // loader: 'expose-loader?$'
                use: {
                    loader: 'expose-loader',
                    options: '$'
                }
            },
            //  编译less和sass, 需要安装less node-sass less-loader sass-loader
            {
                 test: /\.(less)$/i,
                loader: ['style-loader', 'css-loader', 'less-loader']
           },
          {
               test: /\.(scss)$/i,
               loader: ['style-loader', 'css-loader', 'sass-loader']
          },
          {
                test: /\.css$/, // 转换文件的匹配正则
                loader: ['style-loader', 'css-loader']
           },
            
            // url-loader可以在文件比较小的时候,直接变成base64内嵌到页面里面, 用了它就不要用file-loader
            {test: /\.(png|jpg|gif|svg|bmp|ttf|woff)/,
                use: {
                    loader: 'url-loader',
                    options: {
                        limit: 5 * 1024,
                        outputPath: 'images/' // 指定输出目录
                    }
                }
            },
            {
              // 这个file-loader可以处理任意的二进制,字体,图片从源文件拷贝到目标目录
               test: /\.(png|jpg|gif|svg|bmp)/,
               use: {
                   loader: 'file-loader',
                   options: {
                         outputPath: 'images/'  // 指定输出目录
                     }
                 }
            },
            // 可以解析html里面的img的src
            {
                test: /\.(htm|html)$/i,
                loader: 'html-withimg-loader'
            },
            
        ]
    },
    // 提取公共代码
    optimization: {
        splitChunks: {
          chunks: 'async',
          minSize: 30000,
          maxSize: 0,
          minChunks: 1,
          maxAsyncRequests: 5,
          maxInitialRequests: 3,
          automaticNameDelimiter: '~',
          automaticNameMaxLength: 30,
          name: true,
          cacheGroups: {
            vendors: {
              test: /[\\/]node_modules[\\/]/,
              priority: -10
            },
            default: {
              minChunks: 2, // 最少两个文件包含才是公共的
              priority: -20,
              reuseExistingChunk: true
            }
          }
        }
      },
    plugins: [
        cssExtract,  // 把页面中的css单独提出来打包
        lessExtract,  // 把页面中的less单独提出来打包
        sassExtract,  // // 把页面中的sass单独提出来打包
        //下面两个配合hot热更新,不常用,可以不知道
        // new webpack.HotModuleReplacementPlugin(),
        // new webpack.NamedModulesPlugin(), // 用名称代替id
       
        new CopyPlugin([ // 拷贝不要编译的源文件到打包文件里面
            { from: path.resolve(__dirname, 'src/public'), 
                to: path.resolve(__dirname, 'dist/public')}
          ]),
        new MiniCssExtractPlugin({  // css代码压缩
            // Options similar to the same options in webpackOptions.output
            // all options are optional
            filename: '[name].css',
            chunkFilename: '[id].css',
            ignoreOrder: false, // Enable to remove warnings about conflicting order
          }),
        // 自动向模块内部注入变量
        new webpack.ProvidePlugin({
            $: 'jquery'
        }),
        // 自动清除dist目录
        new CleanWebpackPlugin({
            cleanOnceBeforeBuildPatterns: [path.join(__dirname, 'dist')]
        }),
        // 此插件可以自动产出html文件,一般项目会放一个模版html用于打包
        ...pages.map(item => {
            return new HtmlWebpackPlugin({
                template: './src/index.html', // 指定产出的模版
                filename: `${item}.html`, // 产出的html文件名
                title: `${item}`, // 可以使用变量
                chunks: [`${item}`, 'vendor'], // 在产出的html文件里引入哪些代码块, 跟多入口的entry对应
                hash: true, //可以清除缓存,会在资源后面加上?hash
                minify: {
                    removeAttributeQuotes: true
                }
            })
        }),
        // scope hositing,减少函数声明,把函数合并
        new webpack.optimize.ModuleConcatenationPlugin(),
    ],
    // 压缩js
   optimization: {
        minimizer: [new UglifyJsPlugin()],
   },
    // 配置此静态文件服务器,可以用来预览打包后的项目,是放到内存中的文件,有缓存,304
 devServer: { 
 //热加载
        hot: true,
        inline: true,
        contentBase: './dist', 
        host: 'localhost',  // 访问的host
        port: 8080, // 端口
       compress: true, // 服务器返回给客户端的时候是否开启gzip压缩
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,561评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,218评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,162评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,470评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,550评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,806评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,951评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,712评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,166评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,510评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,643评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,306评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,930评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,745评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,983评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,351评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,509评论 2 348

推荐阅读更多精彩内容

  • 我是魏翊锜,自己从去年9月份开始筹建了一间学习少儿英语的学校,然而这教学的道路却并不是如想的那般一帆风顺。 ...
    魏翊锜阅读 210评论 0 0
  • 2017年7月19,星期三,天气多云 昨晚回到家已经接近了半夜,看到了于浩晨在离门口很近的地方睡下了,也许是出于心...
    于浩晨阅读 258评论 0 8
  • 除了生死,都是小事。可是对宇宙来说,生死都是小事。 所以第一篇小事献给“生死”。献给我差一点满90的外婆。 外婆明...
    大城小茹阅读 573评论 3 7
  • 01. 在网上遇到一位做互联网创客的旧时朋友,上次遇到他是十几年以前,当时还是一个毛头小子,在我寝室宿舍楼下,截住...
    汗颜的泥巴阅读 438评论 0 2