zoukankan      html  css  js  c++  java
  • webpack4之路(2)

    tips:上一篇文章我们已经一起学习了webpack的安装、打包与构建本地服务。现在我们一起学习Loader吧……

    什么是loader?

    在官网中loader的解释是对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript 或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

    安装配置css-loader

    如果我们要加载一个css文件,需要先安装style-loader与css-loader

    npm i style-loader css-loader -D // i是install的简称 -D表示生产环境使用

    webpack.config.js

    const path = require('path')
    module.exports = {
        mode: 'development',
        entry: {
            index: './scripts/index.js' // 入口文件,若不配置webpack4将自动查找src目录下的index.js文件
        },
        output: {
            filename: '[name].bundle.js', // 输出文件名,[name]表示入口文件js名
            path: path.join(__dirname, 'dist') // 输出文件路径
        },
        devServer: {
            host: 'localhost', // 主机地址
            compress: true, // 开发服务器是否启动gzip等压缩
            contentBase: './dist',//开发服务运行时的文件根目录
            open:true, // 自动打开浏览器
            inline: true,
            port: 9000 // 监听的端口
        },
        module: {
            rules: [
                {
                    test: /.css$/, // 正则匹配以.css结尾的文件
                    use: ['style-loader', 'css-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
                }
            ]
        }
    }

    我们在webpack目录下新建style文件夹,并在文件夹内建立index.css文件

    index.css

    /* style.css */
    body{
        background: pink;
    }

    在index.js中将它引入

    import '../style/index.css' // 导入css
    let body = document.getElementsByTagName("body")[0]
    let div = document.createElement('div')
    div.innerText = 'init webpack'
    body.appendChild(div)

    现在我们就可以检阅我们的成果了,npm run server.成功背景色已经变了。

     配置sass

    npm i sass-loader node-sass -D // 因为sass-loader依赖于node-sass,所以还要安装node-sass

    在webpack.config.js新增sass的rules:

    const path = require('path')
    module.exports = {
        mode: 'development',
        entry: {
            index: './scripts/index.js' // 入口文件,若不配置webpack4将自动查找src目录下的index.js文件
        },
        output: {
            filename: '[name].bundle.js', // 输出文件名,[name]表示入口文件js名
            path: path.join(__dirname, 'dist') // 输出文件路径
        },
        devServer: {
            host: 'localhost', // 主机地址
            compress: true, // 开发服务器是否启动gzip等压缩
            contentBase: './dist',//开发服务运行时的文件根目录
            open:true, // 自动打开浏览器
            inline: true,
            port: 9000 // 监听的端口
        },
        module: {
            rules: [
                {
                    test: /.css$/, // 正则匹配以.css结尾的文件
                    use: ['style-loader', 'css-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
                },
                {
                    test: /.(scss|sass)$/, // 正则匹配以.scss或者.sass结尾的文件
                    use: ['style-loader', 'css-loader', 'sass-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
                }
            ]
        }
    }

    在style文件夹新建color.scss文件

    /* color.scss */
    $red: red;
    body {
      color: $red;
    }

    在index.js文件中引入color.scss文件

    import '../style/index.css' // 导入css
    import '../style/color.scss' // 导入scss
    
    let body = document.getElementsByTagName("body")[0]
    let div = document.createElement('div')
    div.innerText = 'init webpack'
    body.appendChild(div)

    运行npm run server重新启动服务,就可以看到字体已经发生改变

     类似图片loader、字体loader等使用也与css loader一样。官网有详细说明.

    什么是Babel

    babel是一个JS编译器,用来转换最新的JS语法,比如把ES6, ES7等语法转化成ES5语法,从而能够在大部分浏览器中运行。像箭头函数,就可以做转换。babel在执行过程中,分三步:先分析(parsing)、再转化、最后生成代码。
    Babel的安装与配置
    npm i babel-core babel-loader babel-preset-env  -D
    // babel-preset-env的env表示是对当前环境的预处理,而不是像以前使用babel-preset-es2015只能针对某个环境

    在 webpack .config.js中,需要添加 babel-loader 等到 module 的 loaders 列表中

    const path = require('path')
    module.exports = {
        mode: 'development',
        entry: {
            index: './scripts/index.js' // 入口文件,若不配置webpack4将自动查找src目录下的index.js文件
        },
        output: {
            filename: '[name].bundle.js', // 输出文件名,[name]表示入口文件js名
            path: path.join(__dirname, 'dist') // 输出文件路径
        },
        devServer: {
            host: 'localhost', // 主机地址
            compress: true, // 开发服务器是否启动gzip等压缩
            contentBase: './dist',//开发服务运行时的文件根目录
            open:true, // 自动打开浏览器
            inline: true,
            port: 9000 // 监听的端口
        },
        module: {
            rules: [
                {
                    test: /.css$/, // 正则匹配以.css结尾的文件
                    use: ['style-loader', 'css-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
                },
                {
                    test: /.(scss|sass)$/, // 正则匹配以.scss或者.sass结尾的文件
                    use: ['style-loader', 'css-loader', 'sass-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
                },
                {
                    test: /.js$/,
                    loader: ['babel-loader'],
                    exclude: /node_modules/ // 不包括依赖内的js文件
                }
            ]
        }
    }

    上面的新增的配置,遇到JS文件就会先用babel-loader处理,exclude表示排除node_modules文件夹里的文件。loader配置就OK了,但是这样还不能发挥Babel的作用。要在项目根目录webpack文件夹下创建一个.babelrc文件,添加代码:

    /* .babelrc 使用时把注释删掉,该文件不能添加注释*/
    {
      "presets": [
        "@babel/preset-env"
      ]
    }

     当我们需要对项目中一些组件进行懒加载时,可以使用Babel的另一个插件

    npm i babel-plugin-syntax-dynamic-import -D

    在.babelrc文件中加入plugins配置:

    /* .babelrc 使用时把注释删掉,该文件不能添加注释 */
    {
      "presets": [
        "@babel/preset-env"
      ],
      "plugins": [
        "syntax-dynamic-import"
      ]
    }

    在scripts文件夹创建helper.js

    console.log('this is helper')

    修改index.js

    import '../style/index.css' // 导入css
    import '../style/color.scss' // 导入scss
    
    const App = function () {
        let div = document.createElement('div')
        div.setAttribute('id', 'app')
        document.body.appendChild(div)
        let dom = document.getElementById('app')
        dom.innerHTML = 'init webpack'
        let button = document.createElement('button')
        button.innerText = 'click me'
        button.onclick = () => {
            const help = () => import('./helper')
            help()
        }
        document.body.appendChild(button)
    }
    const app = new App()

    然后进行打包npm run server,报错 了

     提示在依赖里找不到babel-core 。这是个大坑,至少我被坑了很久。最后开始去百度找到解决方案有两种

    npm i babel-loader@7 babel-core babel-preset-env -D // 回退低版本
    npm i babel-loader @babel/core @babel/preset-env webpack -D // 更新到最高版本

    反正我反复重新安装依赖,都是各种报错。最后终于明白了原因是:

    babel-loader和babel-core版本不对应所产生的,

    • babel-loader 8.x对应babel-core 7.x
    • babel-loader 7.x对应babel-core 6.x

    最后给大家看下我的package.json就有种恍然大悟的感觉

    {
      "name": "webpack_demo",
      "version": "1.0.0",
      "description": "my first webpack",
      "main": "index.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
        "server": "webpack-dev-server --mode development "
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "neo-async": "^2.6.1",
        "save-dev": "0.0.1-security"
      },
      "devDependencies": {
        "@babel/core": "^7.8.7",
        "@babel/preset-env": "^7.8.7",
        "babel-loader": "^8.0.4",
        "babel-plugin-syntax-dynamic-import": "^6.18.0",
        "babel-preset-env": "^1.7.0",
        "css-loader": "^3.4.2",
        "html-webpack-plugin": "^3.2.0",
        "loader-runner": "^3.1.0",
        "node-sass": "^4.13.1",
        "sass-loader": "^8.0.2",
        "style-loader": "^1.1.3",
        "webpack": "^4.42.0",
        "webpack-cli": "^3.3.11",
        "webpack-dev-server": "^3.10.3"
      }
    }

    之前我的babel-loader一直是7的版本,后来升级到8的版本就解决了此问题。真是无比开心~~~~

    来查看我们刚刚配置的bable有没有成功吧

     还记得我们之前写的点击事件是ES6的箭头函数吧。现在已变成ES5的语法,证明已经使用成功。

     查阅资料:

    1)https://www.jianshu.com/p/74cb6203c39f  (Cannot find module '@babel/core’)

    2)https://segmentfault.com/a/1190000017898866(babel-loader使用)

    3)https://www.cnblogs.com/BetterMan-/p/9867642.html (webpack 4X学习)

    4)https://www.webpackjs.com/loaders/babel-loader/ (loader官网介绍)

  • 相关阅读:
    【bzoj1174】[Balkan2007]Toponyms Trie树
    【bzoj1786】[Ahoi2008]Pair 配对 dp
    【bzoj3956】Count 单调栈+可持久化线段树
    【bzoj4605】崂山白花蛇草水 权值线段树套KD-tree
    【bzoj3696】化合物 树形dp
    【bzoj1150】[CTSC2007]数据备份Backup 模拟费用流+链表+堆
    【bzoj3671】[Noi2014]随机数生成器 贪心
    【bzoj4653】[Noi2016]区间 双指针法+线段树
    【bzoj4197】[Noi2015]寿司晚宴 分解质因数+状态压缩dp
    用Python操作Named pipe命名管道,实用做法——os.read 或 os.write
  • 原文地址:https://www.cnblogs.com/yilihua/p/12494927.html
Copyright © 2011-2022 走看看