webpack 环境搭建

webpack 环境搭建

npm 初始化项目

yarn init

安装webpack依赖

yarn add webpack webpack-dev-server webpack-cli @webpack-cli/init --dev

webpack 初始化

npx webpack-cli init

? Will your application have multiple bundles? Yes
? Type the names you want for your modules (entry files), separated by comma [example: app,vendor] app
? What is the location of "app"? [example: ./src/app] ./src/app
? Which folder will your generated bundles be in? [default: dist]: dist
? Will you be using ES2015? Yes
? Will you use one of the below CSS solutions? SASS
yarn add v1.12.1

添加编译插件

## 二选一
## 1. class 写法 向下兼容
yarn add @babel/plugin-proposal-class-properties --dev
## 2. babel 支持 import 
## yarn add @babel/plugin-syntax-dynamic-import --dev
yarn add @babel/preset-env @babel/core cross-env --dev

安装loader

yarn add html-withimg-loader url-loader file-loader style-loader postcss-loader --dev

插件安装

yarn add mini-css-extract-plugin uglifyjs-webpack-plugin clean-webpack-plugin copy-webpack-plugin extract-css html-webpack-plugin --dev

安装webpack-chain

yarn add webpack-chain --dev

此处webpack-chain5.0.1版本,是针对webpack 4维护的,需特别注意

github地址:webpack-chain

创建webpack.config.js

const path = require('path');
const isProd = process.env.NODE_ENV === 'production';
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const WebpackChain = require('webpack-chain');

const config = new WebpackChain();

config.when(isProd,config=>{
    config.entry('index').add('./src/index.js');
}).when(!isProd,config=>{
    config.entry('index').add('./src/index.js');
})
// Modify output settings
    .output
    .path(path.join(__dirname, "dist")).filename('[name].js').end()
    .when(isProd, config => {
        config.mode('production');
    }).when(!isProd,config=>{
    config.mode('development').devtool('source-map');
}).end();

/**
 * module
 */
config
    .module
    .rule("compile")
    .test(/\.js$/)
    .include.add(path.join(__dirname,'src')).end()
    .exclude.add(/node_modules/).end()
    .use('babel').loader("babel-loader")
    .options({
        presets: ['@babel/preset-env'],
        plugins: ['@babel/plugin-proposal-class-properties']
    });

config.module
    .rule('images')
    .test(/\.(png|jpg|jpeg|gif)/)
    .use('url-loader')
    .loader('url-loader')
    .options({
        limit: 1 * 1024,
        name: path.posix.join("images","[name].[ext]")
    })

// do not base64-inline SVGs.
// https://github.com/facebookincubator/create-react-app/pull/1180
config.module
    .rule('svg')
    .test(/\.(svg)(\?.*)?$/)
    .use('url-loader')
    .loader('url-loader')
    .options({
        limit: 1024 * 3,//30kb
        fallback: 'file-loader'
    })

config.module
    .rule("fonts")
    .test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i)
    .use('url-loader')
    .loader('url-loader')
    .options({
        limit: 10000,
        fallback: {
            loader: 'file-loader',
            options: {
                name: path.posix.join("fonts","[name].[ext]")
            }
        }
    });

config.when(isProd,config=>{
    config.module.rule("css").test(/\.(sa|sc|c)ss$/)
        .use("style").loader(MiniCssExtractPlugin.loader);
}).when(!isProd,config=>{
    config.module.rule("css").test(/\.(sa|sc|c)ss$/)
        .use("style-loader").loader("style-loader");
});

config.module.rule("css").test(/\.(sa|sc|c)ss$/)
    .use('css').loader("css-loader").end()
    .use('postcss-loader').loader('postcss-loader');

config.module.rule("scss").test(/\.(sa|sc)ss$/).use("sass-loader").loader("sass-loader");

config.module.rule("lass").test(/\.less$/).use("less-loader").loader("less-loader");

//config.module.rule("html").test(/\.(htm|html)$/i).use("html").loader('html-withimg-loader');

/**
 * plugin
 */
config.when(isProd,config=>{
    const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    const CopyWebpackPlugin = require("copy-webpack-plugin");

    config.plugin("clear").use(new CleanWebpackPlugin([path.join(__dirname, 'dist')]));
    config.optimization.splitChunks({
        cacheGroups: {
            commons: {
                chunks: "initial",
                name: "common",
                minChunks: 2,
                maxInitialRequests: 5, // The default limit is too small to showcase the effect
                minSize: 0, // This is example is too small to create commons chunks
                reuseExistingChunk: true // 可设置是否重用该chunk(查看源码没有发现默认值)
            }
        }
    });
    config.plugin("js").use(new UglifyJSPlugin({}));
    config.plugin('extract-css')
        .use(MiniCssExtractPlugin, [{
            filename: "css/[name].css",
            chunkFilename: "css/[name].css"
        }]);
    // config.plugin('copy').use(new CopyWebpackPlugin([
    //     {
    //         from:"./src/sass",
    //     }
    // ]))
})

const HtmlWebpackPlugin = require('html-webpack-plugin');
config.plugin("html").use(HtmlWebpackPlugin, [{
    /*
     template 参数指定入口 html 文件路径,插件会把这个文件交给 webpack 去编译,
     webpack 按照正常流程,找到 loaders 中 test 条件匹配的 loader 来编译,那么这里 html-loader 就是匹配的 loader
     html-loader 编译后产生的字符串,会由 html-webpack-plugin 储存为 html 文件到输出目录,默认文件名为 index.html
     可以通过 filename 参数指定输出的文件名
     html-webpack-plugin 也可以不指定 template 参数,它会使用默认的 html 模板。
     */
    template: "./public/index.html",
    filename:"index.html",
    /*
     因为和 webpack 4 的兼容性问题,chunksSortMode 参数需要设置为 none
     https://github.com/jantimon/html-webpack-plugin/issues/870
     */
    chunksSortMode: 'none',
    xhtml: true,
    minify: {
        collapseWhitespace: false, //删除空格,但是不会删除SCRIPT、style和textarea中的空格
        conservativeCollapse: false, //删除空格,总是保留一个空格
        removeAttributeQuotes: false, //删除引号,删除不需要引号的值
        useShortDoctype: false, //使用短的文档类型
        removeComments: true,
        collapseBooleanAttributes: true,
        removeScriptTypeAttributes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
    }
}]);


config.when(isProd,config=>{

}).when(!isProd,config=>{
    config.devServer.host('localhost').port(8080).open(process.os === 'darwin');
})

config.resolve.alias.set("@",path.join(__dirname,"src"));

// Export the completed configuration object to be consumed by webpack
module.exports = config.toConfig();

添加启动脚本

修改package.json文件中scripts节点,加入如下配置:

  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server",
    "build": "cross-env NODE_ENV=production webpack"
  }

创建postcss.config.js

module.exports = {
    plugins: {
        autoprefixer: {
            "browsers": [
                "ie >= 9",
                "ff >= 30",
                "chrome >= 34",
                "safari >= 7",
                "opera >= 23"
            ]
        }
    }
}

创建src/index.js

export default  class demo {
    constructor(){
        console.log("init");
    }
}

创建example/index.js

import Demo from "../src/index";

const demo = new Demo();

根目录创建index.html

启动

yarn run dev

原文链接

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 全局安装webpack 全局安装webpack会有个问题,就是当你有两个项目依赖于不同版本的webpack,就会有...
    説好的妹紙呢阅读 1,803评论 0 11
  • 写在开头 先说说为什么要写这篇文章, 最初的原因是组里的小朋友们看了webpack文档后, 表情都是这样的: (摘...
    Lefter阅读 5,269评论 4 31
  • 1. 新建一个文件夹,命名为 webpack-cli , webpack-cli 就是你的项目名,项目名建议使用小...
    鲁大师666阅读 1,459评论 1 3
  • 一直只是听说过vue.js很火,但是从来没有接触过,这次准备用它做个项目试试,顺便也学习一下前端开发,在网上试了很...
    delicacylee阅读 661评论 0 5
  • 题诗舞剑言罢举杯,千思万绪也不如半杯浊酒惹人醉。折折转转百转低回,前路莫退,几多险阻已难归。岁月蹉跎,一辈又一辈,...
    bdjb阅读 159评论 0 6