webpack-contrib/expose-loader

issue with jquery ....

sunnysideup opened this issue · 3 comments

We are using webpack 3:

Here are our config:

/*
    Imports
*/

import webpack from 'webpack';
import path from 'path';
import DashboardPlugin from 'webpack-dashboard/plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';


/*
    Useful constants
*/

const SITE_NAME = path.basename(path.join(__dirname, '/../../'));
const THEME_NAME = path.basename(__dirname);

/*
    Plugin configuration
*/

//different css points
const extractEditor = new ExtractTextPlugin({
    filename: 'css/editor.css',
});
const extractMain = new ExtractTextPlugin({
    filename: 'css/style.css',
});

//define plugins
let plugins = [];

const IS_PROD = process.env.NODE_ENV === 'production';

if(IS_PROD) {
    plugins.push(
        new webpack.optimize.UglifyJsPlugin(),
        extractEditor,
        extractMain
    );


//development
} else {
    plugins.push(
        //auto updating on dev server
        new webpack.HotModuleReplacementPlugin(),
        //shows relative path in HotModuleReplacement
        new webpack.NamedModulesPlugin(),
        //sexy dashboard
        new DashboardPlugin(),
        extractEditor
    );
}

plugins.push(new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery",
        "window.jQuery": "jquery"
}))

const sources = [`../${THEME_NAME}_base/src`, `../${THEME_NAME}_mysite/src`];

const sassFolders = sources.map((source) => path.resolve(source, "scss"))
    .concat(sources.map((source) => path.resolve(source, "sass")));

//HMR can be fixed by using basic loaders instead of textExtract
const sassLoaderExtract =    {
    fallback: 'style-loader',
    use: [
        'css-loader',
        {
            loader: 'postcss-loader',
            options: {
                sourceMap: true
            }
        },
        {
            loader: 'sass-loader',
            options: {
                sourceMap: true
            }
        },
    ]
}

const styleLoaders = [{
    //basic css
    test: /\.css/i,
    use: ['style-loader', 'css-loader']
}, {
    //main styles
    test: /[^editor].\.s(a|c)ss$/i,
    include: sassFolders,
    use: extractMain.extract(sassLoaderExtract)
}, {
    //styles for editor
    test: /editor\.s(a|c)ss/i,
    include: sassFolders,
    use: extractEditor.extract(sassLoaderExtract)
}];

const jsLoaders = [
    // KEEP THE CODE BELOW AND TURN ON IF NEEDED....
    // {
    //     //eslint check
    //     enforce: 'pre',
    //     test: /\.js$/i,
    //     exclude: /node_modules/,
    //     use: {
    //         loader: 'eslint-loader'
    //     }
    // },
    {
        //js compilation
        test: /\.js$/i,
        include: sources.map((source) => path.resolve(source, "src")),
        exclude: /node_modules/,
        use: {
            loader: 'babel-loader',
            options: {
                cacheDirectory: true,
                presets: [require.resolve("babel-preset-es2015")]
            }
        }
    },
    {
        test: require.resolve('jquery'),
        use: [{
            loader: 'expose-loader',
            options: 'jQuery'
        },{
            loader: 'expose-loader',
            options: '$'
        }]
    }
];

const imageLoaders = [
    {
        test: /\.(png|jpg|gif)$/i,
        include: sources.map((source) => path.resolve(source, "images")),
        use: [
            {
                loader: 'url-loader',
                options: {
                    limit: 30000,
                    name: 'images/[name].[ext]'
                }
            },
            {
                loader: 'image-webpack-loader',
                options: {
                    optipng: {
                        optimizationLevel: 5
                    },
                    mozjpeg: {
                        interlaced: true,
                    }
                }
            }
        ]
    },
    {
        test: /\.svg$/i,
        use: 'svg-inline-loadera'
    }
];

/*
    Main Config Object
*/
export default {
    //what files to start from
    //bundle should include main.js from all sources
    entry: path.resolve(`../${THEME_NAME}_mysite/src`, "main.js"),
    //access from client
    output: {
        path: path.resolve(`../${THEME_NAME}_dist/`, ''),
        publicPath: `/themes/${THEME_NAME}_dist/`,
        filename: 'bundle.js'
    },
    //loaders
    module: {
        rules: styleLoaders.concat(jsLoaders).concat(imageLoaders)
    },
    //extra settings
    resolve: {
        modules: [
            path.join(__dirname, "node_modules"),
        ],
        alias: {
            base: path.resolve(`../${THEME_NAME}_base/src/`),
            'jquery': 'jquery/dist/jquery',
            'jQuery': 'jquery/dist/jquery'
        },
        extensions: [".js", ".jsx"]
    },
    devServer: {
        disableHostCheck: true,
        host: '0.0.0.0',
        hot: true,
        port: 3000,
        publicPath: `/themes/${THEME_NAME}_dist/`,
        proxy: {
            '/': {
                'target': {
                    'host': `${SITE_NAME}.localhost`,
                    'protocol': 'http',
                    'port': 80
                },
                changeOrigin: true,
                secure: false
            }
        },
        stats: 'errors-only'
    },
    plugins: plugins
};

in main.js we have:

import $ from 'jquery';

Works fine on build, but it does not work fine when NPM is watching / running (jquery is NOT recognised inside webpack nor outside of it at all).

Any ideas?

@sunnysideup your want change jquery in watch mode and it is run rebuild, right? Looking on code expose-loader seems it is expected behavior, can your create minimum test repo, because use code from issue to reproduce is very inconvenient, thanks!

Also having this.

Please update the dependencies to the latest versions. If the problem still appears, open a new issue with a minimally reproducible repository.