Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 431|回复: 0

webpack4 前端框架基础配置实例-解决css分离图片路径问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-25 17:32:23 | 显示全部楼层 |阅读模式

    1.安装nodejs

    2. 需要全局和项目安装webpack和webpack-dev-server

    npm install webpack webpack-dev-server -g
    npm install webpack webpack-dev-server --save-dev

    本框架的功能如下:

      1、babel babel-folyfill 处理js

      2、css、less 自动编译成css文件并添加前缀

      3、less语法编译

      4、图片处理

      5、开发环境页面自动刷新

      6、resolve 解析

      7、引用HTML模板

      8、css分离

      9、打包优化,大文件拆分

      10、原生ajax请求(get、post)

      11、纯原生分页

    文件目录结构如图所示:

    项目github地址https://github.com/HelloWoed/webpack-project-demo

    说明一下:由于使用了css分离,会导致css背景图片和html img标签图片路径出错问题,这里的解决办法是:css中使用的图片用assets/static/images中的图片,css-loader配置的options中url:false,这样在解析css时就不会处理css图片路径,

    {
                    test:/\.less$/,
                    use: ExtractTextWebpackPlugin.extract({
                        fallback:'style-loader',
                        use:[
                            {
                                loader:'css-loader',
                                options:{
                                    url:false,
                                    importLoaders:1
                                }
                            },
                             'postcss-loader', 
                             'less-loader'
                        ],
                        publicPath: '../css'   
                      }),
                      exclude: path.resolve(__dirname,'./node_modules')
                },
    

      最后将static目录拷贝到相应的打包目录(这里使用的是 copy-webpack-plugin 插件)static目录为你静态数据目录

     

    new copyWebpackPlugin([
                {
                from:__dirname+'/src/assets/static',//打包的静态资源目录地址
                to:'./static' //打包到dist下面的static
                }
            ]),
    

     

      

     

    package.json配置文件如下:

    {
      "name": "testwebpack",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "webpack --mode production --watch --progress --display-reasons --color",
        "dev": "webpack-dev-server --inline --progress  --mode development"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@babel/core": "^7.1.2",
        "@babel/preset-env": "^7.1.0",
        "autoprefixer": "^9.2.1",
        "babel-core": "^6.26.3",
        "babel-loader": "^8.0.4",
        "babel-polyfill": "^6.26.0",
        "clean-webpack-plugin": "^0.1.19",
        "css-loader": "^1.0.0",
        "extract-text-webpack-plugin": "^4.0.0-beta.0",
        "file-loader": "^2.0.0",
        "html-webpack-plugin": "^3.2.0",
        "html-withimg-loader": "^0.1.16",
        "less": "^3.8.1",
        "less-loader": "^4.1.0",
        "postcss-loader": "^3.0.0",
        "style-loader": "^0.23.1",
        "url-loader": "^1.1.2",
        "webpack": "^4.21.0",
        "webpack-cli": "^3.1.2",
        "webpack-dev-server": "^3.1.9"
      }
    }
    

      

    webpack.config.js文件配置如下:(有很多配置项可根据具体情况设置,不用全部配置)

    const path = require("path");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    // 拆分css样式的插件
    const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    const copyWebpackPlugin = require('copy-webpack-plugin');
    
    function resolve (dir) {
        return path.join(__dirname, './', dir)
    }
    console.log(resolve ('abcdefghijklmnop'));
    module.exports = {
        mode:'development',
        // entry:['babel-polyfill','./main.js'],//可以有多个入口文件
        entry:{
            babelPolyfill:'babel-polyfill',//添加了这个东西,才能完美的将ES6转码,否则Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,如:Set Map
            app:'./main.js',//可以有多个入口文件
        },
        output:{
            path:path.resolve(__dirname,"dist"),//输出文件路径    path:path.join(__dirname,"dist","js")
            filename:"./js/[name].bundle.js",//"[name].[chunckhash].bundle.js"    输出的文件名称
        },
        devtool: 'inline-source-map',
        resolve: {
            extensions: ['.js', '.json'],
            alias: {
                '@': resolve('src'),
            }
        },
        //在webpack4之前,提取公共代码都是通过一个叫CommonsChunkPlugin的插件来办到的。到了webpack4以后,内置了一个一模一样的功能,就是所谓的“优化”
    //    optimization: {  // 提取公共代码
    //         splitChunks: {
    //             cacheGroups: {
    //                 vendor: {   // 剥离第三方插件
    //                     test: /node_modules/,   // 指定是node_modules下的第三方包
    //                     chunks: 'initial',
    //                     name: 'vendor',  // 打包后的文件名,随意命名    
    //                     priority: 10    // 设置优先级,防止和自定义的公共代码提取时被覆盖,不进行打包
    //                 },
    //                 utils: { // 抽离自己写的公共代码,utils这个名字可以随意起
    //                     chunks: 'initial',
    //                     name: 'utils',  // 任意命名
    //                     minSize: 0    // 只要超出0字节就生成一个新包
    //                 }
    //             }
    //         }
    //     },
        performance: {
            hints: "warning", // 枚举
            maxAssetSize: 30000000, // 整数类型(以字节为单位)
            maxEntrypointSize: 50000000, // 整数类型(以字节为单位)
            assetFilter: function(assetFilename) {
            // 提供资源文件名的断言函数
            return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
            
            }
        },
        module:{
            rules:[
                {
                    test:/\.js$/,
                    exclude: /node_modules/,//有变化了处理,没有变化则不处理
                    // include:[resolve('src'), resolve('test')],//需要处理的文件夹
                    loader:"babel-loader"
                },
                {
                    test:/\.css$/,
                    // loader:"style-loader!css-loader",
                    use: ExtractTextWebpackPlugin.extract({
                        // 将css用link的方式引入就不再需要style-loader了
                        fallback: "style-loader",
                        use:[
                            {
                                loader:'css-loader',
                                options:{
                                    url:false, //false  css中加载图片的路径将不会被解析 不会改变
                                    importLoaders:1
                                }
                            },
                            'postcss-loader', 
                        ],
                        publicPath: '../css'       
                    })
                    // use: [ //以行内样式style的标签写进打包后的html页面中
                    //     {
                    //         loader: "style-loader"
                    //     }, 
                    //     {
                    //         loader: "css-loader",
                    //         options: {
                    //             modules: true, // 指定启用css modules
                    //             localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的类名格式
                    //         }
                    //     },
                    //     {
                    //         loader: "postcss-loader"
                    //     }
                    // ]
                },
                {
                    test:/\.less$/,
                    use: ExtractTextWebpackPlugin.extract({
                        fallback:'style-loader',
                        use:[
                            {
                                loader:'css-loader',
                                options:{
                                    url:false,
                                    importLoaders:1
                                }
                            },
                             'postcss-loader', 
                             'less-loader'
                        ],
                        publicPath: '../css'   
                      }),
                      exclude: path.resolve(__dirname,'./node_modules')
                },
                {
                    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                    loader: 'url-loader',
                    options: {
                      limit: 10000,
                      name: "[name].[hash:4].[ext]",
                      outputPath: "./images",//打包后图片文件输出路径
                      publicPath:'./images'
                    }
                },
                {
                    test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
                    loader: 'url-loader',
                    options: {
                      limit: 10000,
                      name: 'media/[name].[hash:7].[ext]'
                    }
                },
                {
                    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                    loader: 'url-loader',
                    options: {
                      limit: 10000,
                      name: 'fonts/[name].[hash:7].[ext]'
                    }
                },
                { //页面中会用到img标签,img引用的图片地址也需要一个loader来处理,这样再打包后的html文件下img就可以正常引用图片路径了
                    test: /\.(htm|html)$/,
                    use: 'html-withimg-loader'
                }
            ]
        },
        plugins:[
            // 打包前先清空
            new CleanWebpackPlugin('dist/') ,
            new ExtractTextWebpackPlugin({ //样式文件单独打包
                filename: "./css/[name].min.css",  //指定生成的文件名称
                disable: false,  //是否禁用此插件
                allChunks: true
              }),
            new HtmlWebpackPlugin({
                template:"./index.html",//本地模板文件的位置,支持加载器(如handlebars、ejs、undersore、html等),如比如 handlebars!src/index.hbs;
                filename: './index.html',//输出文件的文件名称,默认为index.html,不配置就是该文件名;此外,还可以为输出文件指定目录位置(例如'html/index.html')
                title: 'Webpack App',//生成的html文档的标题
                chunks:["app"],
                inject:true,//1、true或者body:所有JavaScript资源插入到body元素的底部2、head: 所有JavaScript资源插入到head元素中3、false: 所有静态资源css和JavaScript都不会注入到模板文件中
                showErrors:true,//是否将错误信息输出到html页面中
                hash:true,//是否为所有注入的静态资源添加webpack每次编译产生的唯一hash值
                minify: false,//传递 html-minifier 选项给 minify 输出
                favicon: "",//添加特定的 favicon 路径到输出的 HTML 文件中。
            }),
            new copyWebpackPlugin([
                {
                from:__dirname+'/src/assets/static',//打包的静态资源目录地址
                to:'./static' //打包到dist下面的static
                }
            ]),
        ],
        devServer: {
            publicPath: '/',//
            contentBase: path.resolve(__dirname, 'dist'),//此处的路径必须和输出output文件的路径一致 否则无法自动更新,或者是基于output的相对路径
            compress: true,
            historyApiFallback: true,//在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
            inline: true,//设置为true,当源文件改变时会自动刷新页面
            // grogress: true,
            host: 'localhost',// 默认是localhost
            port: 9000,//指定用于侦听请求的端口号
            open:true,//当open启用时,开发服务器将打开浏览器。
            //hot: true,// 开启热更新,开启热加载还需在主入口js文件中配置
            // openPage:'index.html',//指定在打开浏览器时导航到的页面。
            overlay: {//当存在编译器错误或警告时,在浏览器中显示全屏覆盖,显示警告和错误:
                warnings: true,
                errors: true
            },
            proxy: {//代理配置
                '/api': {
                    target: 'http://localhost:3000',
                    pathRewrite: {'^/api' : ''},//如果不想/api传递,我们需要重写路径
                }
            },
            
        }
    }
    

      

    postcss.config.js文件配置如下:

    module.exports = {
        plugins: [
            require('autoprefixer')
        ]
    }
    

      

     

    const path = require( "path");
    const HtmlWebpackPlugin = require( "html-webpack-plugin");
    // 拆分css样式的插件
    const ExtractTextWebpackPlugin = require( 'extract-text-webpack-plugin');
    const CleanWebpackPlugin = require( 'clean-webpack-plugin');
    const copyWebpackPlugin = require( 'copy-webpack-plugin');

    function resolve ( dir) {
    return path. join( __dirname, './', dir)
    }
    console. log( resolve ( 'abcdefghijklmnop'));
    module. exports = {
    mode: 'development',
    // entry:['babel-polyfill','./main.js'],//可以有多个入口文件
    entry:{
    babelPolyfill: 'babel-polyfill', //添加了这个东西,才能完美的将ES6转码,否则Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,如:Set Map
    app: './main.js', //可以有多个入口文件
    },
    output:{
    path:path. resolve( __dirname, "dist"), //输出文件路径 path:path.join(__dirname,"dist","js")
    filename: "./js/[name].bundle.js", //"[name].[chunckhash].bundle.js" 输出的文件名称
    },
    devtool: 'inline-source-map',
    resolve: {
    extensions: [ '.js', '.json'],
    alias: {
    '@' : resolve( 'src'),
    }
    },
    //在webpack4之前,提取公共代码都是通过一个叫CommonsChunkPlugin的插件来办到的。到了webpack4以后,内置了一个一模一样的功能,就是所谓的“优化”
    // optimization: { // 提取公共代码
    // splitChunks: {
    // cacheGroups: {
    // vendor: { // 剥离第三方插件
    // test: /node_modules/, // 指定是node_modules下的第三方包
    // chunks: 'initial',
    // name: 'vendor', // 打包后的文件名,随意命名
    // priority: 10 // 设置优先级,防止和自定义的公共代码提取时被覆盖,不进行打包
    // },
    // utils: { // 抽离自己写的公共代码,utils这个名字可以随意起
    // chunks: 'initial',
    // name: 'utils', // 任意命名
    // minSize: 0 // 只要超出0字节就生成一个新包
    // }
    // }
    // }
    // },
    performance: {
    hints: "warning", // 枚举
    maxAssetSize: 30000000, // 整数类型(以字节为单位)
    maxEntrypointSize: 50000000, // 整数类型(以字节为单位)
    assetFilter : function( assetFilename) {
    // 提供资源文件名的断言函数
    return assetFilename. endsWith( '.css') || assetFilename. endsWith( '.js');
     
    }
    },
    module:{
    rules:[
    {
    test: / \. js $ /,
    exclude: /node_modules/, //有变化了处理,没有变化则不处理
    // include:[resolve('src'), resolve('test')],//需要处理的文件夹
    loader: "babel-loader"
    },
    {
    test: / \. css $ /,
    // loader:"style-loader!css-loader",
    use: ExtractTextWebpackPlugin. extract({
    // 将css用link的方式引入就不再需要style-loader了
    fallback: "style-loader",
    use:[
    {
    loader: 'css-loader',
    options:{
    url: false, //false css中加载图片的路径将不会被解析 不会改变
    importLoaders: 1
    }
    },
    'postcss-loader',
    ],
    publicPath: '../css'
    })
    // use: [ //以行内样式style的标签写进打包后的html页面中
    // {
    // loader: "style-loader"
    // },
    // {
    // loader: "css-loader",
    // options: {
    // modules: true, // 指定启用css modules
    // localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的类名格式
    // }
    // },
    // {
    // loader: "postcss-loader"
    // }
    // ]
    },
    {
    test: / \. less $ /,
    use: ExtractTextWebpackPlugin. extract({
    fallback: 'style-loader',
    use:[
    {
    loader: 'css-loader',
    options:{
    url: false,
    importLoaders: 1
    }
    },
    'postcss-loader',
    'less-loader'
    ],
    publicPath: '../css'
    }),
    exclude: path. resolve( __dirname, './node_modules')
    },
    {
    test: / \. ( png | jpe ? g | gif | svg )( \? . * ) ? $ /,
    loader: 'url-loader',
    options: {
    limit: 10000,
    name: "[name].[hash:4].[ext]",
    outputPath: "./images", //打包后图片文件输出路径
    publicPath: './images'
    }
    },
    {
    test: / \. ( mp4 | webm | ogg | mp3 | wav | flac | aac )( \? . * ) ? $ /,
    loader: 'url-loader',
    options: {
    limit: 10000,
    name: 'media/[name].[hash:7].[ext]'
    }
    },
    {
    test: / \. ( woff2 ? | eot | ttf | otf )( \? . * ) ? $ /,
    loader: 'url-loader',
    options: {
    limit: 10000,
    name: 'fonts/[name].[hash:7].[ext]'
    }
    },
    { //页面中会用到img标签,img引用的图片地址也需要一个loader来处理,这样再打包后的html文件下img就可以正常引用图片路径了
    test: / \. ( htm | html ) $ /,
    use: 'html-withimg-loader'
    }
    ]
    },
    plugins:[
    // 打包前先清空
    new CleanWebpackPlugin( 'dist/') ,
    new ExtractTextWebpackPlugin({ //样式文件单独打包
    filename: "./css/[name].min.css", //指定生成的文件名称
    disable: false, //是否禁用此插件
    allChunks: true
    }),
    new HtmlWebpackPlugin({
    template: "./index.html", //本地模板文件的位置,支持加载器(如handlebars、ejs、undersore、html等),如比如 handlebars!src/index.hbs;
    filename: './index.html', //输出文件的文件名称,默认为index.html,不配置就是该文件名;此外,还可以为输出文件指定目录位置(例如'html/index.html')
    title: 'Webpack App', //生成的html文档的标题
    chunks:[ "app"],
    inject: true, //1、true或者body:所有JavaScript资源插入到body元素的底部2、head: 所有JavaScript资源插入到head元素中3、false: 所有静态资源css和JavaScript都不会注入到模板文件中
    showErrors: true, //是否将错误信息输出到html页面中
    hash: true, //是否为所有注入的静态资源添加webpack每次编译产生的唯一hash值
    minify: false, //传递 html-minifier 选项给 minify 输出
    favicon: "", //添加特定的 favicon 路径到输出的 HTML 文件中。
    }),
    new copyWebpackPlugin([
    {
    from:__dirname+ '/src/assets/static', //打包的静态资源目录地址
    to: './static' //打包到dist下面的static
    }
    ]),
    ],
    devServer: {
    publicPath: '/', //
    contentBase: path. resolve( __dirname, 'dist'), //此处的路径必须和输出output文件的路径一致 否则无法自动更新,或者是基于output的相对路径
    compress: true,
    historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
    inline: true, //设置为true,当源文件改变时会自动刷新页面
    // grogress: true,
    host: 'localhost', // 默认是localhost
    port: 9000, //指定用于侦听请求的端口号
    open: true, //当open启用时,开发服务器将打开浏览器。
    //hot: true,// 开启热更新,开启热加载还需在主入口js文件中配置
    // openPage:'index.html',//指定在打开浏览器时导航到的页面。
    overlay: { //当存在编译器错误或警告时,在浏览器中显示全屏覆盖,显示警告和错误:
    warnings: true,
    errors: true
    },
    proxy: { //代理配置
    '/api' : {
    target: 'http://localhost:3000',
    pathRewrite: { '^/api' : ''}, //如果不想/api传递,我们需要重写路径
    }
    },
     
    }
    }
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-24 08:32 , Processed in 0.083662 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表