webpack - webpack4学习笔记,爱上webpack

经过上周的webpack4学习,踩了不少坑

比如不理解为什么webpack-dev-server启动后本地没有dist文件;

比如babel用错版本,使用了babel-core 6.26.3、babel-loader 8.0.4,导致无法编译成ES5,在IE下报错;

总算有点入门了

之前用过vue-cli集成的webpack3.x,假设你使用过webapck3,应该对entry/output/loader/plugin配置和功能有所了解,这里就不记录了,有空再补充


相比webpack3,webpack4有几个改动点:

  • webpack4官方称可以做到零配置

  • webapck4默认有出口入口,entry output可以不配置了,entry默认值为:./src/index.js,output默认值为:./dist/main.js

  • webpack4内置mode,可以指定development、production、none,分别对应着不同的环境。默认的是production

  • webpack-cli抽离出来了,以前集成在webpack包里,现在要单独安装npm i webpack-cli --sace-dev

  • 对CSS的支持方面,废弃了ExtractTextPlugin,改用MiniCssExtractPlugin插件


另外,踩得几个坑

  • 开发模式(“dev”: “webpack-dev-server --mode development”)本地磁盘没有创建dist文件夹和打包文件,F12的source中看到的文件存储在内存之中

  • webpack编译成ES5后,Object.defineProperty(fn, name, ObjectFactory(name)),有使用defineProperty属性,该属性支持IE9及以上

  • 注意你使用的webpack版本、babel版本、babel-loader版本要对应,否则会报错,要对应;

    • babel 6之后命名改了,之前为"babel-core":"^6.26.3"
    • 现在为"@babel/core":"^7.1.0",安装时要注意
    • //webpack 4.x | babel-loader 8.x | babel 7.x,编译成ES5写法为options:{presets: [’@babel/preset-env’]}
    • //webpack 4.x | babel-loader 7.x | babel 6.x,编译成ES5写法为options:{presets: [‘es2015’]}

贴一下我的package.json和webpack.config.js

  • 目录结构
    webpack - webpack4学习笔记,爱上webpack_第1张图片

  • package.json

{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "First webpack-demo",
  "private": true,
  "scripts": {
    "build": "webpack --mode production --config webpack.config.js",
    "dev": "webpack-dev-server --mode development"
  },
  "author": "IronKee",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.1.0",
    "babel-loader": "8.0.4",
    "babel-polyfill": "^6.26.0",
    "@babel/preset-env": "^7.1.0",
    "clean-webpack-plugin": "^1.0.0",
    "css-loader": "^2.1.0",
    "file-loader": "^3.0.1",
    "html-webpack-plugin": "^4.0.0-beta.3",
    "less": "^3.9.0",
    "less-loader": "^4.1.0",
    "lodash": "^4.17.11",
    "mini-css-extract-plugin": "^0.5.0",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.2",
    "webpack": "^4.28.2",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.14"
  }
}
  • webpack.config.js(学习过程中把注解都加上了,所以注解比较多)
const path = require('path');
const HtmlWebpackPlugin=require('html-webpack-plugin');
const CleanWebpackPlugin=require('clean-webpack-plugin');
const webpack=require('webpack');
const MiniCssExtractPlugin=require("mini-css-extract-plugin");

module.exports={
    //入口文件
    entry:'./src/index.js',
    //出口文件
    output:{
        //打包文件夹,__dirname是node.js的一个全局环境变量,存储的是文件所在目录
        path:path.resolve(__dirname,'dist'),
        //打包文件名称,可以以name/id/hash放在中括号里区分文件名
        //如果入口文件是多个,这个时候文件名称不能写死,可配合[name][hash:6]区分
        //当entry为数组的时候,webpack会把数组里所有文件打包成一个js文件
        //当entry为对象的时候,webpack会把对象里的文件分别打包成多个js文件
        //filename:'[name]_[hash:6].js'
        filename:'[name].js'
    },
    //模块,借助loader解读CSS、图片转换压缩、es5等
    module: {
        rules: [
            // {
            //     test: /\.css$/, //以点开始css结尾的文件
            //     //顺序不能搞错,这个loader的意思为,在入口文件里找到.css类型的文件,先拿css-loader去处理成浏览器认识的css,再拿style-loader把处理后的css放在页面的style标签里
            //     use: ['style-loader', 'css-loader']
            // },
            // {
            //     test:/\.css$/,
            //     use:[MiniCssExtractPlugin.loader,"css-loader"]  //代替style-loader
            // },
            {
                test:/\.css$/,  //以点开始css结尾的文件
                use:[
                    //这是一个loader,如果loader需要给参数,就写成对象的形式
                    {
                        loader:MiniCssExtractPlugin.loader, //loader是哪个
                        options:{   //所有的配置参数都要放在这个对象里面
                            publicPath:'../'    //这个表示在css文件里但凡用到地址的地方在其前面加个目录'../',这个是为了能找到图片
                        }
                    },
                    'css-loader'    //这个loader没有其它选项就直接写
                ]
            },
            // {
            //     test:/\.(jpg|png|gif)$/,    //找到三种格式中的任意一种
            //     use:['file-loader'] ////解析地址
            // },
            {
                test:/\.(jpg|png|gif)$/,
                //use:['file-loader']
                use:[
                    {
                        loader:'url-loader',    //把图片转成base64
                        options:{
                            limit:50*1024,    //小于50k就会转成base64
                            outputPath: 'images'
                        }
                    }
                ]
                
                //use:'url-loader?limit=50000&outputPath=images'    //loader的另一种写法,与get请求方式相同
            },
            {
                test:/\.less$/,
                use:[    //把less编译到css文件里
                    {
                        loader:MiniCssExtractPlugin.loader,
                        options:{
                            publicPath:'../'
                        }
                    },
                    'css-loader',    //注意顺序
                    'less-loader'
                ]
            },
            // {
            //     test:/\.scss$/,
            //     use:[    //把scss编译到css文件里
            //         {
            //             loader:MiniCssExtractPlugin.loader,
            //             options:{
            //                 publicPath:'../'
            //             }
            //         },
            //         'css-loader',    //注意顺序
            //         'sass-loader'
            //     ]
            // },
            {
                test:/\.js$/,
                use:[
                    {
                        //webpack 4.x | babel-loader 8.x | babel 7.x
                        //webpack 4.x | babel-loader 7.x | babel 6.x
                        loader:'babel-loader',
                        options:{    //env针对的是ES的版本,它会自动选择。react针对的就是react
                            presets: ['@babel/preset-env']
                        }
                    }
                ],
                exclude: /node_modules/,    //不去检查node_modules里的内容,那里的js太多了,会非常慢
                include:path.resolve(__dirname,'src'),    //直接规定查找的范围
            }
        ]
    },
    // //模式选择
    // mode:'development',
    // //loader 转换器
    // loader:{},
    //插件 用于生产模块和各项功能
    plugins:[
        new CleanWebpackPlugin(['./dist']),  //这个一定要放在最上面,作用是先删除dist目录再创建新的dist目录。里面的参数为要删除的目录,放在一个数组里面
        new HtmlWebpackPlugin({
            title:'webpack demo',    /*这个值对应html里的title*/
            template:'./src/index.html',    //模板文件地址
            filename:'index.html',    //文件名,默认为index.html(路径相对于output.path的值)
            inject:'head',    //script标签的位置,true/body为在标签前,head为在里,false表示页面不引入js文件
            hash:true,    //是否为引入的js文件添加hash值
            //chunks:['one'],    //页面里要引入的js文件,值对应的是entry里的key。省略参数会把entry里所有文件都引入
            //excludeChunks:['one'],    //页面里不能引入的js文件,与chunks刚好相反
            minify:{    //html-webpack-plugin内部集成了html-minifier
                collapseWhitespace:false,    //压缩空格
                removeAttributeQuotes:false, //移除引号
                removeComments:true,        //移除注释
            },
        }),
        new webpack.HotModuleReplacementPlugin(),    //引入热更新插件
        new MiniCssExtractPlugin({
            filename:'css/index.css'    //文件目录会放入output.path里
        }),
    ],
    //服务器配置
    devServer:{
        // contentBase: path.resolve(__dirname,'dist'), //设置项目的基本目录结构
        host: 'localhost', //服务器IP配置
        port: '1990', //端口配置
        open:true,    //自动打开刷新页面
        hot:true,    //开启热更新
        // compress: true //服务器压缩是否开启
    }
}
import 'babel-polyfill';    //处理ES6新增的API,需要导入这个模块
import './css/index.css';   //两个点是找上级目录
import './css/index.less';  //引入less文件
// import './css/index.scss';  //引入sass文件

import img1 from './images/img_01.jpg';


const loadImg=img=>{
    const newImg=new Image();
    newImg.onload=()=>document.body.appendChild(newImg);
    newImg.src=img;
};

loadImg(img1);

//ES6
const fn=()=>console.log(123);

//map对象
const map=new Map();
map.set('name','kaivon');
console.log(map);

//Array.from方法
const strArr=Array.from('kaivon');
console.log(strArr);

//Object.assign方法
const t1={a:1};
Object.assign(t1,{b:2},{c:3});
console.log(t1);

//generator
function* bear(){
    console.log('熊大');
    console.log('熊二');
}
bear().next();


<html>
    <head>
        <meta charset="UTF-8">
        
        <title><%= htmlWebpackPlugin.options.title %>title>
    head>
    <body>
        <div id="box">
            这是自带的div
            <p>webpack demop>
            <ul>
                <li><a href="#">reda>li>
                <li><a href="#">greena>li>
                <li><a href="#">bluea>li>
            ul>
        div>
    body>
html>
  • index.css
#box{
    width: 800px;
    height: 500px;
    border: 5px solid #999;
    color: #00f;
    /* background: green; */

    background: url(../images/img_01.jpg);
}
  • index.less
@w:200px;
@border:1px solid #f00;

#box{
    width: @w;
    border: @border;
    ul{
        margin: 0;
        padding: 0;
        list-style: none;
        
        li{
            height: 30px;
            background: #ccc;
            
            a{
              color: #f00;
              &:hover{  //&为上一层选择器
                  color: blue;
              }
            }
        }
    } 
}

写在后面
因为想写一个个人项目练手,学习如何搭建项目、搭建页面,使用es6等,但是发现无从下手,不可能还像以前那样写html引入js和css,想用es6,sass,less,npm包,你的选择貌似只有webpack,gulp等;
webpack是趋势,是最流行的前端构建工具,没有之一,用了它你会发现它非常的强大,非常的方便,怎么说呢,感觉就是标题里写的爱上webpack吧


---- 未完待续 ----

你可能感兴趣的:(webpack)