Skip to content

Instantly share code, notes, and snippets.

@r6203
Created September 30, 2016 19:35
Show Gist options
  • Save r6203/6fe3767c77c1f43d9debe061f98152c5 to your computer and use it in GitHub Desktop.
Save r6203/6fe3767c77c1f43d9debe061f98152c5 to your computer and use it in GitHub Desktop.

Revisions

  1. Robin Altay created this gist Sep 30, 2016.
    283 changes: 283 additions & 0 deletions webpack.config.babel.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,283 @@
    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",
    },
    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,
    query: {
    context: path.join(__dirname, config.source),
    plugins: [
    ...require("phenomic/lib/loader-preset-markdown").default,
    ],
    // see https://phenomic.io/docs/usage/plugins/
    },
    },

    // *.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" ] },
    */
    }
    }