import path from "path" import webpack from "webpack" import ExtractTextPlugin from "extract-text-webpack-plugin" import { phenomicLoader } from "phenomic" import PhenomicLoaderFeedWebpackPlugin from "phenomic/lib/loader-feed-webpack-plugin" import pkg from "./package.json" export default (config = {}) => { const postcssPlugins = () => [ require("stylelint")(), require("postcss-cssnext")({ browsers: "last 2 versions", features: { customProperties: { variables: { mainColor: "#111", mainColorContrasted: "#eee", }, }, }, }), require("postcss-reporter")(), ...!config.production ? [ require("postcss-browser-reporter")(), ] : [], ] return { ...config.dev && { devtool: "#cheap-module-eval-source-map", }, phenomic: { query: { context: path.join(__dirname, config.source), plugins: [ ...require("phenomic/lib/loader-preset-default").default, ...require("phenomic/lib/loader-preset-markdown").default, ], // see https://phenomic.io/docs/usage/plugins/ }, }, module: { noParse: /\.min\.js/, // webpack 1 loaders: [ // webpack 2 /* rules: [ */ // *.md => consumed via phenomic special webpack loader // allow to generate collection and rss feed. { // phenomic requirement test: /\.md$/, loader: phenomicLoader, }, // *.json => like in node, return json // (not handled by webpack by default) { test: /\.json$/, loader: "json-loader", }, // *.js => babel + eslint { test: /\.js$/, include: [ path.resolve(__dirname, "scripts"), path.resolve(__dirname, "src"), ], loaders: [ "babel-loader?cacheDirectory", "eslint-loader" + (config.dev ? "?emitWarning" : ""), ], }, // ! \\ // by default *.css files are considered as CSS Modules // And *.global.css are considered as global (normal) CSS // *.css => CSS Modules { test: /\.css$/, exclude: /\.global\.css$/, include: path.resolve(__dirname, "src"), // webpack 1 loader: ExtractTextPlugin.extract( "style-loader", [ `css-loader?modules&localIdentName=${ config.production ? "[hash:base64:5]" : "[path][name]--[local]--[hash:base64:5]" }`, "postcss-loader", ].join("!"), ), // webpack 2 /* loader: ExtractTextPlugin.extract({ fallbackLoader: "style-loader", loader: [ { loader: "css-loader", query: { modules: true, localIdentName: ( config.production ? "[hash:base64:5]" : "[path][name]--[local]--[hash:base64:5]" ), }, }, { loader: "postcss-loader", // query for postcss can't be used right now // https://github.com/postcss/postcss-loader/issues/99 // meanwhile, see webpack.LoaderOptionsPlugin in plugins list // query: { plugins: postcssPlugins }, }, ], }), */ }, // *.global.css => global (normal) css { test: /\.global\.css$/, include: path.resolve(__dirname, "src"), // webpack 1 loader: ExtractTextPlugin.extract( "style-loader", [ "css-loader", "postcss-loader" ].join("!"), ), // webpack 2 /* loader: ExtractTextPlugin.extract({ fallbackLoader: "style-loader", loader: [ "css-loader", { loader: "postcss-loader", // query for postcss can't be used right now // https://github.com/postcss/postcss-loader/issues/99 // meanwhile, see webpack.LoaderOptionsPlugin in plugins list // query: { plugins: postcssPlugins }, }, ], }), */ }, // ! \\ // If you want global CSS only, just remove the 2 sections above // and use the following one // ! \\ If you want global CSS for node_modules only, just uncomment // this section and the `include` part // { // test: /\.css$/, // // depending on your need, you might need to scope node_modules // // for global CSS if you want to keep CSS Modules by default // // for your own CSS. If so, uncomment the line below // // include: path.resolve(__dirname, "node_modules"), // loader: ExtractTextPlugin.extract({ // fallbackLoader: "style-loader", // loader: [ // "css-loader", // { // loader: "postcss-loader", // query: { "plugins": postcssPlugins }, // }, // ] // }), // }, // ! \\ if you want to use Sass or LESS, you can add sass-loader or // less-loader after postcss-loader (or replacing it). // ! \\ You will also need to adjust the file extension // and to run the following command // // Sass: `npm install --save-dev node-sass sass-loader` // https://github.com/jtangelder/sass-loader // // LESS: npm install --save-dev less less-loader // https://github.com/webpack/less-loader // copy assets and return generated path in js { test: /\.(html|ico|jpe?g|png|gif)$/, loader: "file-loader", query: { name: "[path][name].[hash].[ext]", context: path.join(__dirname, config.source), }, }, // svg as raw string to be inlined { test: /\.svg$/, loader: "raw-loader", }, ], }, // webpack 1 postcss: postcssPlugins, plugins: [ // webpack 2 /* // You should be able to remove the block below when the following // issue has been correctly handled (and postcss-loader supports // "plugins" option directly in query, see postcss-loader usage above) // https://github.com/postcss/postcss-loader/issues/99 new webpack.LoaderOptionsPlugin({ test: /\.css$/, options: { postcss: postcssPlugins, // required to avoid issue css-loader?modules // this is normally the default value, but when we use // LoaderOptionsPlugin, we must specify it again, otherwise, // context is missing (and css modules names can be broken)! context: __dirname, }, }), */ new PhenomicLoaderFeedWebpackPlugin({ // here you define generic metadata for your feed feedsOptions: { title: pkg.name, site_url: pkg.homepage, }, feeds: { // here we define one feed, but you can generate multiple, based // on different filters "feed.xml": { collectionOptions: { filter: { layout: "Post" }, sort: "date", reverse: true, limit: 20, }, }, }, }), // webpack 1 new ExtractTextPlugin("[name].[hash].css", { disable: config.dev }), // webpack 2 /* new ExtractTextPlugin({ filename: "[name].[hash].css", disable: config.dev, }), */ ...config.production && [ // webpack 2 // DedupePlugin does not work correctly with Webpack 2, yet ;) // https://github.com/webpack/webpack/issues/2644 new webpack.optimize.DedupePlugin(), new webpack.optimize.UglifyJsPlugin( { compress: { warnings: false } } ), ], ], output: { path: path.join(__dirname, config.destination), publicPath: config.baseUrl.pathname, filename: "[name].[hash].js", }, // webpack 1 resolve: { extensions: [ ".js", ".json", "" ], root: [ path.join(__dirname, "node_modules") ], }, resolveLoader: { root: [ path.join(__dirname, "node_modules") ] }, // webpack 2 /* resolve: { extensions: [ ".js", ".json" ] }, */ } }