实现css-loader、less-loader、style-loader

less-loader

less-loader.js

let less = require('less');
function loader(source) {
    let css;
    less.render(source, function (err, r) { // r.css
        css = r.css;
    });
    return css;
}
module.exports = loader;

css-loader

css-loader.js

function loader(source) {
    let reg = /url\((.+?)\)/g;
    let pos = 0;
    let current;
    let arr = ['let list = [];'];
    while (current = reg.exec(source)) {
        let [matchUrl, g] = current;
        console.log(matchUrl, g);
        let last = reg.lastIndex-matchUrl.length;
        arr.push(`list.push(${JSON.stringify(source.slice(pos, last))})`);
        pos = reg.lastIndex;
        // 把g替换成require的写法 =》 url(require('***'))
        arr.push(`list.push('url('+require(${g})+')')`);

    }
    arr.push(`list.push(${JSON.stringify(source.slice(pos))})`);
    arr.push(`module.exports = list.join('')`);
    console.log(arr.join('\r\n'));

    return arr.join('\r\n');
}
module.exports = loader;

style-loader

style-loader.js

let loaderUtils = require('loader-utils');
function loader(source) {
    // 在style-loader中,导出一个脚本
    let str = `
    let style = document.createElement('style');
    style.innerHTML = ${JSON.stringify(source)};
    document.head.appendChild(style);
    `;
    return str;
}
loader.pitch = function(remainingRequest) {
    // 剩余的请求
    // 让style-loader去处理less-loader!css-loader!./index.less;
    console.log(remainingRequest);
    console.log(loaderUtils.stringifyRequest(this, '!!' + remainingRequest));
    let str = `
    let style = document.createElement('style');
    style.innerHTML = require(${loaderUtils.stringifyRequest(this, '!!' + remainingRequest)});
    document.head.appendChild(style);
    `;
    return str;
};
module.exports = loader;

webpack.config.js

let path= require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'index.js',
        path: path.resolve(__dirname, 'dist')
    },
    mode: 'development',
    resolveLoader: {
        modules: ['node_modules', path.resolve(__dirname, 'loaders')],
    },
    devtool: "source-map",
    // watch: true,
    module: {
        // loader的分类,pre在前面的, post在后面, 然后就是普通normal
        // loader的顺序  pre +normal + inline + post;   从右向左,从下倒上
        rules: [
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            },
            {
                test: /(\.png)|(\.svg)/,
                use: {
                    // loader: "file-loader"
                    loader: "url-loader",
                    options: {
                        limit: 1
                    }
                }
            },
            {
                test: /\.js$/,
                use: {
                    loader: "banner-loader",
                    options: {
                        text: 'zhangfeng',
                        filename: path.resolve(__dirname, 'banner.js'),
                    }
                }
            }
            // {
            //     test: /\.js$/,
            //     use: {
            //         loader: 'babel-loader',
            //         options: {
            //             presets: [
            //                 '@babel/preset-env'
            //             ]
            //         }
            //     }
            // }
        ]
    }
};

你可能感兴趣的:(webpack系列)