webpack打包多页面demo

项目地址:
https://github.com/withwz/webpack-mulitpage-demo


webpack打包多页demo
配置了scss

使用scss来写css提高效率

配置了postcss

自动补全css浏览器前缀和rem自动转换
无需再写css3各浏览器的前缀,也无需用rem这种难以心算的单位来布局了,设计稿多少就敲多少px。
[外链图片转存失败(img-Xh9j4RkG-1566297319449)(./redeme-img/postcss.png)]

内置了jquery

直接可以使用“&”无需引入script文件或者用require import来引入。

可以放心的写多页应用

可以像图片中目录一样嵌套,
建议每一个文件中只包含一个*.html,一个*.scss,一个*.ts,这样结构是最清晰的表现形式,可以在一个文件中嵌套另一个文件保存同样的内容,程序会递归所有的文件夹。

❗ 不建议一个文件中包含多个*.html.




源代码
目录结构

在这里插入图片描述

package.json
{
  "name": "wptest",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --config webpack.config.js",
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/jquery": "^3.3.31",
    "autoprefixer": "^9.6.1",
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^3.2.0",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "html-webpack-plugin": "^3.2.0",
    "jquery": "^3.4.1",
    "lodash": "^4.17.15",
    "node-sass": "^4.12.0",
    "postcss-loader": "^3.0.0",
    "postcss-nested": "^4.1.2",
    "postcss-px2rem": "^0.3.0",
    "sass-loader": "^7.2.0",
    "style-loader": "^1.0.0",
    "ts-loader": "^6.0.4",
    "typescript": "^3.5.3",
    "uglifyjs-webpack-plugin": "^2.2.0",
    "webpack": "^4.39.2",
    "webpack-cli": "^3.3.7",
    "webpack-dev-server": "^3.8.0",
    "webpack-merge": "^4.2.1"
  }
}

webpack.config.js
const rimraf = require('rimraf')
const webpackConfig = process.env.NODE_ENV === 'development'
  ? require('./build/webpack.dev.js')
  : require('./build/webpack.prod.js')
if (process.env.NODE_ENV !== 'development') {
  rimraf('./dist', function (err) {
    if (err) throw err
  })
}
module.exports = webpackConfig
webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const webpack = require('webpack')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const config = require('./entries');

console.log('============================', config.entries, '=============================')
const entries = {};
config.entries.forEach(function (entry) {
  entries[entry.entryName] = entry.entry;
});
console.log('............................', entries, '.................................')

const webpackConfig = {
  entry: entries,
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: [
            'css-loader',
            'postcss-loader',
            'sass-loader',
          ],
        })
      },
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js']
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery',
      'window.$': 'jquery',
    }),
    new CleanWebpackPlugin(),
    /*
     https://doc.webpack-china.org/plugins/extract-text-webpack-plugin/
     它会将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件。
     因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css)当中。
     如果你的样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载。
    */
    new ExtractTextPlugin({
      filename: 'asset/css/[name].[sha1:contenthash:hex:7].css',
      allChunks: true
    }),
  ],
  output: {
    filename: 'asset/js/[name].bundle.js',
    path: path.resolve(__dirname, '../dist'),
    publicPath: '/'
  }
};


config.entries.forEach(function (entry) {
  const options = {
    filename: entry.filename,
    template: entry.template,
    chunks: ['manifest', 'vendor', 'app', entry.entryName],
  }
  // https://github.com/jantimon/html-webpack-plugin
  webpackConfig.plugins.push(new HtmlWebpackPlugin(options))
});


module.exports = webpackConfig
entries.js
let path = require('path');
let fs = require('fs');

let dirSrc = path.resolve(__dirname, '../src')

let entriesConfig = [
  {
    entryName: 'index/index',
    entry: path.resolve(dirSrc, 'index.ts'),
    filename: 'index.html',
    template: path.resolve(dirSrc, '../index.html')
  }
];

//获取src下的所有目录
let dirPages = fs.readdirSync(dirSrc).filter(function (dirName) {
  return fs.statSync(dirSrc + '/' + dirName).isDirectory()
})

dirPages.forEach(pageWalk)
function pageWalk(pageName) {
  let filemark = 'index'
  let pagePath = path.resolve(dirSrc, pageName)
  let files = fs.readdirSync(pagePath)
  let fileHTML = filemark + '.html'
  let fileTS = filemark + '.ts'

  //获取有*.ts和*.html的文件
  if (files.indexOf(fileHTML) === -1 || files.indexOf(fileTS) === -1) return

  let filename = pageName + '/' + fileHTML
  console.log('==========', path.resolve(dirSrc, pageName, fileTS), '=================')
  entriesConfig.push({
    entryName: pageName + '/' + filemark,
    entry: path.resolve(dirSrc, pageName, fileTS),
    filename: filename,
    template: path.resolve(dirSrc, filename)
  })

  let subDirs = files.filter(function (file) {
    return fs.statSync(pagePath + '/' + file).isDirectory()
  }).map(function (dirName) {
    return pageName + '/' + dirName
  })

  if (subDirs.length) {
    subDirs.forEach(pageWalk)
  }
}

module.exports = {
  entries: entriesConfig,
}
webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  devtool: 'inline-source-map',
  devServer: {
    contentBase: './dist'
  }
});
webpack.prod.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  devtool: 'inline-source-map',
  devServer: {
    contentBase: './dist'
  }
});
postcss.config.js
module.exports = {
  plugins: [
    require('autoprefixer')({
      browsers: ['last 100 versions']      //必须设置支持的浏览器才会自动添加添加浏览器兼容
    }),
    require('postcss-px2rem')
  ]
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值